【问题标题】:JPasswordField.getPassword() is still not secured?JPasswordField.getPassword() 仍然不安全?
【发布时间】:2016-08-18 00:54:45
【问题描述】:

抱歉再次提出这个话题,我已经仔细阅读了另一个类似的问题 Why does JPasswordField.getPassword() create a String with the password in it?

但是我仍然认为 JpasswordField 实现存在漏洞。我仍然看到密码存储在内存中可能是不同的数据类型,而不是字符串。

我做的步骤: 从 Oracle 下载 JPasswordField 演示代码 https://docs.oracle.com/javase/tutorial/displayCode.html?code=https://docs.oracle.com/javase/tutorial/uiswing/examples/components/PasswordDemoProject/src/components/PasswordDemo.java

并运行它。它将弹出密码对话框。

输入“bugaboo”

按回车键,查看密码是否正确。 (我删除了输入的密码,有/没有这个delete的结果都是一样的)

此时,由于代码中清除密码内容的原因

    //Zero out the password.
    Arrays.fill(correctPassword,'0');

我希望内存中没有剩余的 bugaboo,但确实存在。 我用http://www.sweetscape.com/010editor/检查了内存内容,仍然看到明文的“bugaboo”

结论:原因是 JpasswordField 在内部使用 PlainDocument,它会在你的记忆中留下所输入内容的全部历史记录。因此你无法完全清除内存中的密码明文。

因此,将 getPassword() 用作 char[] 并在之后清除它并没有多大好处。

请赐教。

【问题讨论】:

  • 它必须存储在某个地方,nu
  • @EJP 关键是您无法可靠地清除PlainDocument。所以这个问题的答案是“是”。 (FWIW IIRC,如果您添加 ActionListener,您还将获得 String。)
  • @TomHawtin-tackline 关键是它无法受到保护,如果“受保护”的意思是“内存中没有密码”。可以完成的只是提供一个基于char[] 的API,以避免更明显的基于String 的漏洞利用。

标签: java security memory jpasswordfield


【解决方案1】:

当您从JPasswordField 检索密码时,您只会得到一个副本。 JPasswordField 中的 Document 对象仍然有一个包含密码的自己的字符数组。我猜这是您在内存查看器中看到的值。

现在一个想法是在验证密码后清除JPasswordField

passwordField.setText("");

具有讽刺意味的是,这会引发一个 UndoableEditEvent 包含一个 javax.swing.text.GapContent$RemoveUndo 对象,该对象将密码存储为 String 对象 - 我们一开始就试图避免这种情况。

【讨论】:

    猜你喜欢
    • 2012-02-04
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-11
    • 2019-01-04
    • 1970-01-01
    • 2014-11-06
    相关资源
    最近更新 更多