【发布时间】:2011-03-27 22:39:44
【问题描述】:
我正在阅读一本 java 认证书籍中的 java.io.Console 类,可能我错过了前一章中的一些基本内容,但有人可以解释以下内容吗?
它提到,readPassword 方法返回一个字符数组而不是一个字符串,以防止潜在的黑客找到这个字符串然后找到密码。
字符数组如何更安全?如果您可以获取数组中的值,那么您是否可以不创建一个脚本来循环遍历各种组合并最终找到密码?
【问题讨论】:
我正在阅读一本 java 认证书籍中的 java.io.Console 类,可能我错过了前一章中的一些基本内容,但有人可以解释以下内容吗?
它提到,readPassword 方法返回一个字符数组而不是一个字符串,以防止潜在的黑客找到这个字符串然后找到密码。
字符数组如何更安全?如果您可以获取数组中的值,那么您是否可以不创建一个脚本来循环遍历各种组合并最终找到密码?
【问题讨论】:
Console 对象通过其 readPassword 方法支持安全密码输入。此方法通过两种方式帮助保护密码输入。首先,它禁止回显,因此密码在用户屏幕上不可见。其次,readPassword 返回一个字符数组,而不是字符串,因此可以覆盖密码,一旦不再需要它就将其从内存中删除。
这里的想法是,您可以在验证密码后立即调用Arrays.fill(或等效项)来“清空”字符数组,从那时起,密码不再存储在内存中。由于字符串是不可变的,因此字符串将保留在堆中,直到它被垃圾收集 - 如果它设法让自己被拘留,这将永远不会,并且在任何其他情况下仍然可能“太长”。虽然它一直存在,但它可能很容易被各种载体嗅探。
【讨论】:
这是最佳实践之一。这没有多大意义,但我们这样做是为了过上轻松的生活。
如果密码在内存中,缓冲区读取溢出可能允许读取它。或者它可以保存在核心转储或休眠映像中。使用可变的char[] 允许数据在希望狭窄的窗口之后被销毁,只要它没有被复制到字符串中,复制到其他地方,它可能在缓冲区中,垃圾收集喜欢移动对象等。
在 Swing 中有一个有趣的例子,其中JPasswordField 提供了一个char[] 方式来读取数据,但是例如如果它有一个动作监听器(这是一个非常常见的使用方法)。
【讨论】:
String 是一个不可变的类,当密码存储在 String 中时,您无法控制其生命周期,这意味着它可以在内存中长期可用(并且受内存转储等影响) (即使它没有被实习,它会在内存中直到 JVM 退出)。当它存储在字符数组中时,您可以清除数组,从而在验证后从内存中删除密码。
【讨论】: