一尘不染

为什么 char[] 优于 String 的密码?

javascript

在 Swing 中,密码字段有一个getPassword()(returns char[]) 方法,而不是通常的getText()(returns String)方法。同样,我遇到了一个不用于String处理密码的建议。

为什么String在密码方面会对安全构成威胁?使用起来感觉不方便char[]。


阅读 178

收藏
2022-01-13

共2个答案

一尘不染

字符串是不可变的。这意味着一旦您创建了String,如果另一个进程可以转储内存,那么(除了反射之外)您无法在垃圾收集开始之前摆脱数据。

使用数组,您可以在完成后显式擦除数据。你可以用你喜欢的任何东西覆盖数组,密码不会出现在系统的任何地方,甚至在垃圾收集之前。

所以是的,这是一个安全问题——但即使使用也char[]只会减少攻击者的机会之窗,而且仅适用于这种特定类型的攻击。

如评论中所述,垃圾收集器移动的数组可能会将数据的杂散副本留在内存中。我相信这是特定于实现的 - 垃圾收集器可能会随时清除所有内存,以避免这种事情。即使是这样,仍然存在char[]包含实际字符作为攻击窗口的时间。

2022-01-13
一尘不染

虽然这里的其他建议似乎有效,但还有一个很好的理由。使用plain String,您有更高的机会意外将密码打印到日志、监视器或其他一些不安全的地方。char[]不那么脆弱。

考虑一下:

public static void main(String[] args) {
    Object pw = "Password";
    System.out.println("String: " + pw);

    pw = "Password".toCharArray();
    System.out.println("Array: " + pw);
}

打印:

String: Password
Array: [C@5829428e
2022-01-13