为什么我们从char数组中的控制台读取密码而不是String

可能重复:
为什么char []比字符串更适合密码?

当我准备OCPJP我遇到了主题 – “从控制台读取用户输入”。

有一个例子,它在String引用中读取username ,而在char[]数组中读取password ,但我无法理解为什么它使用了char数组..这是代码: –

 Console console = System.console(); String username = console.readLine("User Name? "); char[] password = console.readPassword("Password? "); 

这引起了我的疑问。为什么我们没有使用String引用来存储密码。 由于Strings不可变的,因此在字符串中读取密码必须更安全,因为其内容无法更改。

那么,在char[]数组中读取password重点是什么呢?

谁能在这件事上解释一下?

正如你所说,字符串是不可变的,这意味着一旦你创建了字符串,如果另一个进程可以转储内存,就没有办法(好吧,可能有reflection)你可以在GC启动之前摆脱数据。

使用数组,您可以在完成数据后显式擦除数据:您可以使用您喜欢的任何内容覆盖数组,并且即使在垃圾回收之前,密码也不会出现在系统的任何位置。

来自java.io.Console的Javadoc :

安全说明 :如果应用程序需要读取密码或其他安全数据,则应使用readPassword()readPassword(String, Object...)并在处理后手动将返回的字符数组归零,以最大限度地readPassword(String, Object...)内存中敏感数据的生命周期。

这只是为了防止其他应用程序(如键盘记录程序等)访问密码。

而且如果你使用String ,因为它们是不可变的,修改它们会在内存中创建副本。 在这种情况下,使用char[]可以节省您的时间。 由于它们是可变的,因此它们不会创建副本,您可以在处理后将它们设为null。

由于字符串是不可变的,因此在应用程序处于活动状态时,它们不能被覆盖并保留在内存中。 另一方面, char数组可以清除所有密码信息。

我相信它是这样你可以通过在你不再需要它们时覆盖它们来清除它们。 至少使用Java,如果使用String,那么内存中可能会有剩余的副本。

如果使用for循环覆盖char数组并将每个值设置为0,我认为内存中不会有任何剩余的副本。