Java控制台; readPassword,数组如何防止确定密码值?

时间:2010-08-10 16:29:51

标签: java console passwords

我正在阅读其中一本java认证书中的java.io.Console课程,可能我错过了上一章的基本内容,但有人可以解释下面的内容吗?

它提到,readPassword方法返回一个字符数组而不是String,以防止潜在的黑客发现此字符串,然后找到密码。

字符数组如何更安全?如果您可以获取数组中的值,那么您是否可以创建一个脚本来循环遍历各种组合并最终找到密码?

3 个答案:

答案 0 :(得分:13)

来自documentation

  

Console对象通过其readPassword方法支持安全密码输入。此方法有助于以两种方式保护密码输入。首先,它抑制回显,因此密码在用户屏幕上不可见。其次,readPassword返回一个字符数组,而不是String,因此密码可以被覆盖,一旦不再需要就将其从内存中删除。

这里的想法是,一旦验证了密码,就可以调用Arrays.fill(或等效的)来清空char数组,从那时起,密码就不再存储在内存中了。由于字符串是不可变的,因此字符串将保留在堆中,直到它被垃圾收集 - 如果它设法自己实现内部将永远不会,并且在任何其他情况下仍然可能“太长”。它一直存在,它可能容易被各种载体嗅探。

答案 1 :(得分:4)

这是最好的练习之一。它没有多大意义,但我们这样做是为了过上轻松的生活。

如果密码在内存中,缓冲区读取溢出可以允许它被读取。或者它可以保存在核心转储或休眠图像中。使用mutable char[]允许在一个有希望的狭窄窗口之后销毁数据,只要它没有被复制到字符串中,复制到别处,它可能在缓冲区中,垃圾收集喜欢移动对象等等

Swing中有一个很有趣的例子,其中JPasswordField提供了char[]方式来读取数据,但是如果它有一个动作监听器,例如会从数据中创建一个String (这是一种非常常用的方式)。

答案 2 :(得分:2)

String是一个不可变的类,当密码存储在String中时,你无法控制它的生命周期,这意味着它可以在内存中使用(并且受内存转储等影响)很长一段时间(即使它没有被实现,在JVM退出之前它将在内存中)。当它存储在字符数组中时,您可以清除该数组,从而在验证后从内存中删除密码。