Java JPasswordField.getPassword()仍不安全?
很抱歉再次提起这个话题,我已经仔细阅读了另一个类似的问题 然而,我仍然认为JpasswordField实现中存在漏洞。我仍然看到密码存储在内存中,可能是不同的数据类型,而不是字符串 我所做的步骤: 从Oracle下载JPasswordField演示代码 然后运行它。它将弹出密码对话框 输入“bugaboo” 点击回车键,查看密码是否正确。 (我删除键入的密码,删除/不删除后的最终结果相同) 现在在这一点上,由于代码清除了密码中的内容Java JPasswordField.getPassword()仍不安全?,java,security,memory,jpasswordfield,Java,Security,Memory,Jpasswordfield,很抱歉再次提起这个话题,我已经仔细阅读了另一个类似的问题 然而,我仍然认为JpasswordField实现中存在漏洞。我仍然看到密码存储在内存中,可能是不同的数据类型,而不是字符串 我所做的步骤: 从Oracle下载JPasswordField演示代码 然后运行它。它将弹出密码对话框 输入“bugaboo” 点击回车键,查看密码是否正确。 (我删除键入的密码,删除/不删除后的最终结果相同) 现在在这一点上,由于代码清除了密码中的内容 //Zero out the password.
//Zero out the password.
Arrays.fill(correctPassword,'0');
我希望内存中没有剩余的bugaboo,但是有。
我曾经检查过内存内容,但仍然能看到清晰文本中的“bugaboo”
结论:这是因为JpasswordField在内部使用了PlainDocument,它会将输入内容的整个历史抛在你的记忆中。因此,无法完全清除内存中的密码明文
因此,将getPassword()用作char[]并在之后清除它的努力没有多大好处
请告诉我。当您从
JPasswordField
检索密码时,您只需获得一份副本即可。JPasswordField
中的文档
对象仍然有自己的包含密码的字符数组。我猜这就是你在内存查看器中看到的值
现在的想法是在验证密码后清除JPasswordField
:
passwordField.setText("");
具有讽刺意味的是,这会引发一个
UndoableEditEvent
,其中包含一个javax.swing.text.GapContent$RemoveUndo
对象,该对象将密码存储为String
对象,这是我们一开始就试图避免的事情。它必须存储在某个地方,nu?@EJP关键是您无法可靠地清除普通文档
。所以这个问题的答案是“是”。(FWIW IIRC,如果你添加一个ActionListener
,你也会得到一个String
)@TomHawtin tackline问题的关键是它不能被保护,如果“secured”意味着“内存中没有密码”。我们所能做的就是提供一个基于char[]
的API,以避免更明显的基于String
的漏洞利用。