问题
在Swing中,密码字段有一个getPassword()
(返回char []
)方法,而不是通常的getText()
(返回String
)方法。同样,我遇到了一个不使用String
来处理密码的建议。
为什么String
在密码方面对安全构成威胁?使用char []
感觉不方便。
#1 热门回答(3682 赞)
字符串是不可变的.这意味着一旦创建了String
,如果另一个进程可以转储内存,那么在garbage collectionkicks之前就没有办法(除了544442657)删除数据。
使用数组,您可以在完成数据后明确清除数据。你可以用你喜欢的任何东西覆盖这个数组,甚至在垃圾收集之前密码也不会出现在系统的任何地方。
所以,是的,这个安全问题 - 但即使使用char []
也只会减少攻击者的机会窗口,而且只针对这种特定类型的攻击。
正如在注释中指出的那样,垃圾收集器移动的数组可能会在内存中留下数据的零散副本。我相信这是特定于实现的 - 垃圾收集器可以清除所有内存,以避免这种情况。即使这样,仍然有char []
包含实际字符作为攻击窗口的时间。
#2 热门回答(1070 赞)
虽然这里的其他建议似乎有效,但还有一个很好的理由。使用普通的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
#3 热门回答(604 赞)
引用官方文档,Java Cryptography Architecture guide这是关于char []
与String
密码(关于基于密码的加密,但当然更常见的是关于密码):
将密码收集并存储在java.lang.String类型的对象中似乎是合乎逻辑的。但是,这里有一点需要注意:String类型的对象是不可变的,即没有定义的方法允许您在使用后更改(覆盖)或清零String的内容。此功能使String对象不适合存储安全敏感信息(如用户密码)。您应该始终将安全敏感信息收集并存储在char数组中。
Guideline 2-2 of the Secure Coding Guidelines for the Java Programming Language, Version 4.0也说类似的东西(虽然它最初是在日志的上下文中):
准则2-2:不要记录高度敏感的信息某些信息(如社会安全号码(SSN)和密码)非常敏感。这些信息的保存时间不应超过必要的时间,即使是管理员也不能保存。例如,它不应该被发送到日志文件,并且它的存在不应该通过搜索被检测到。一些瞬态数据可能保存在可变数据结构中,如char数组,并在使用后立即清除。清除数据结构降低了典型Java运行时系统的有效性,因为对象在内存中透明地移动到程序员。本指南还对实施和使用不具备所处理数据的语义知识的低级库有影响。作为一个例子,一个低级别的字符串解析库可能会记录它所处理的文本。应用程序可以使用库解析SSN。这创造了SSN可供管理员访问日志文件的情况。