翻译:https://www.baeldung.com/java-storing-passwords
- 1.尽管使用java.lang.String类型的对象来操纵密码似乎很明显,但Java团队本身还是建议使用char []代替。
- 2.字符串是不可变的
Java中的String是不可变的,这意味着我们无法使用任何高级API对其进行更改。对String对象的任何更改 都会产生一个新的String,将旧的String保留在内存中。
因此,存储在字符串中的密码将在内存中可用,直到垃圾回收器将其清除为止。我们无法控制何时发生,但是此时间段可能比常规对象长得多,因为将字符串保存在字符串池中是为了可重用。
因此,有权访问内存转储的任何人都可以从内存中检索密码。
使用char []数组而不是String,我们可以在完成预期的工作后显式擦除数据。这样,即使在垃圾回收发生之前,我们也将确保从内存中删除密码。
String stringPassword ="password";
System.out.print("密码的值为: ");
System.out.println(stringPassword);
System.out.println("密码的 hashCode 为: "
+ Integer.toHexString(stringPassword.hashCode()));
String newString = "********";
stringPassword.replace(stringPassword, newString);
System.out.println("试图替换密码后的密码值: "+stringPassword);
System.out.println("在尝试替换原始字符串之后 hashCode : "
+ Integer.toHexString(stringPassword.hashCode()));
密码的值为: password
密码的 hashCode 为: 4889ba9b
试图替换密码后的密码值: password
在尝试替换原始字符串之后 hashCode : 4889ba9b
char[] charPassword = new char[]{
'p', 'a', 's', 's', 'w', 'o', 'r', 'd'};
System.out.print("密码的值为: ");
System.out.println(charPassword);
System.out.println(
"密码的 hashCode 为: "
+ Integer.toHexString(charPassword.hashCode()));
Arrays.fill(charPassword, '*');
System.out.print("试图替换密码后的密码值: ");
System.out.println(charPassword);
System.out.println(
"在尝试替换原始字符串之后 hashCode: "
+ Integer.toHexString(charPassword.hashCode()));
密码的值为: password
密码的 hashCode 为: 1218025c
试图替换密码后的密码值: ********
在尝试替换原始字符串之后 hashCode: 1218025c
如我们所见,在尝试替换原始String的内容之后,该值保持不变,并且 hashCode()方法在应用程序的同一执行中未返回不同的值,这意味着原始String保持完整。
对于char []数组,我们能够更改同一对象中的数据。
我们可能会意外打印密码
String passwordString = "password";
char[] passwordArray = new char[]{
'p', 'a', 's', 's', 'w', 'o', 'r', 'd'};
System.out.println("Printing String password -> " + passwordString);
System.out.println("Printing char[] password -> " + passwordArray);
Printing String password -> password
Printing char[] password -> [C@816f27d