ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java中为何用char[]数组来操作密码

2022-07-08 09:00:39  阅读:147  来源: 互联网

标签:Java String format hashCode char 密码 数组 password


1. 概述

本文解释Java中为什么用char[]来表示密码而不是String。
注意本文重点在内存中操作密码的方法而不是存储密码的实际方法,存储密码我们通常放在持久层。
假设我们不能够控制密码的格式(例如密码来自于三方库API的字符串)。尽管看起来用字符串操作密码很合理,但是Java团队还是建议用char[]。

例如,javax.swing中的JPasswordField中,我们可以看到getText()自Java2以来就已被弃用,取而代之的是返回char[]的getPassword()方法。
因此,我们来深入了解一下为什么推荐用char[]来操作密码。

2. 字符串不可变

Java中字符串是不可变的,这意味着我们无法用任何高级API更改它们。对于字符串中的任何一个变更都会产生一个新的字符串,旧的字符串将还保留在内存中。
因此,存储密码的字符串一直在内存中可用直到垃圾收集器清除它。我们无法控制这个回收的过程,而且字符串生存的时间可能比常规对象要长得多,因为为了可重用字符串是保存在字符串池中的。
因为,任何有访问内存权限的人都可以从内存中查看密码。使用char[]我们可以在完成预期工作后显式擦除数据,这样即使在垃圾收集发生之前,我们也可以确保从内存中删除密码。

使用String的场景:

String stringPassword = "password";
System.out.println(String.format("Original String password value: %s", stringPassword));
System.out.println(String.format("Original String password hashCode: %s",
                                 Integer.toHexString(stringPassword.hashCode())));

String newString = "*********";
stringPassword.replace(stringPassword, newString);

System.out.println(String.format("String password value after trying to replace it: %s", stringPassword));
System.out.println(String.format("hashCode after trying to replace the original String: %s",
                                 Integer.toHexString(stringPassword.hashCode())));

输出:

Original String password value: password
Original String password hashCode: 4889ba9b
String password value after trying to replace it: password
hashCode after trying to replace the original String: 4889ba9b

使用char[]的场景:

char[] charPassword = new char[]{'p', 'a', 's', 's', 'w', 'o', 'r', 'd'};

System.out.println(String.format("Original char password value: %s", charPassword));
System.out.println(String.format("Original char password hashCode: %s",
                                 Integer.toHexString(charPassword.hashCode())));

Arrays.fill(charPassword, '*');

System.out.println(String.format("Changed char password value: %s", charPassword));
System.out.println(String.format("Changed char password hashCode: %s",
                                 Integer.toHexString(charPassword.hashCode())));

输出:

Original char password value: [C@51cdd8a
Original char password hashCode: 51cdd8a
Changed char password value: [C@51cdd8a
Changed char password hashCode: 51cdd8a

可以看到,使用String时,替换原始字符串后,值和hashCode都没有变,这意味着String保持不变。
对于char[]数组,值变了hashCode没变说明我们是更改的同一个对象数据。

3. 可以不经意间打印密码

使用char[]中操作密码的另一个好处是可以防止在控制台、监视器或其他不安全的地方记录密码。
下面是代码:

String stringPassword = "password";
char[] charPassword = new char[]{'p', 'a', 's', 's', 'w', 'o', 'r', 'd'};
System.out.println(String.format("Printing String password -> %s", stringPassword));
System.out.println(String.format("Printing char[] password -> %s", charPassword));

输出:

Printing String password -> password
Printing char[] password -> [C@51cdd8a

使用String打印了密码本身,使用char[]输出的[C@51cdd8a 这样密码就不那么容易泄露了。

4. 结论

本文探索了为什么不用字符串来操作密码而使用char[]来操作密码。

标签:Java,String,format,hashCode,char,密码,数组,password
来源: https://www.cnblogs.com/okokabcd/p/16456966.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有