问题

Swing中,密码域(JPasswordField)用getPassword()函数(用来返回char[])取代getText()函数(返回字符串)。在工作中我得到类似的建议是不要用字符串去处理密码相关的问题,为什么涉及到密码问题时字符串会对安全构成威胁呢?(译注:这是提问者在Stackoverflow提了问题,他觉得用char[]处理密码并没有String方便,但为什么还要推荐使用char[]处理呢?下面是几个比较精彩的回答)。

回答1

String在Java中是不可变对象,这就意味着一旦创建了一个字符串,如果另一个进程把尝试内存的数据导出(dump),在GC进行垃圾回收之前该字符串会一直保留在内存中,那么该进程就可以轻易的读取到该字符串。

而对于数组,可以在该数组处理它之后再显示地擦掉数组中内容,可以以任何方式把数组内容覆盖掉,即使是GC触发前密码也不会出现在系统的任何地方。

char[]也只是降低被攻击的概率而已,还是会有一些特定的手法攻破数组处理的密码。

Strings are immutable. That means once you've created the string, if another process can dump memory, there's no way (aside from reflection) you can get rid of the data before GC kicks in.

before

is a security concern - but even using char[] only reducesmay clear all memory as it goes, to avoid this sort of thing. Even if it does, there's still the time during which the char[]

回答2

[] 就没那么显而易见

参考一下这段代码:



1



2



3



4



5



6



7


public static void main(String[] args) {



Object pw = "Password" ;



System.out.println( "String: " + pw);



 



pw = "Password" .toCharArray();



System.out.println( "Array: " + pw);



}




输出结果:



1


String: PasswordArray: [C@5829428e



String you have much higher chances of accidentally printing the password to logs, monitors or some other insecure place. char[]

Consider this:

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

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

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

Prints:

String: Password
Array: [C@5829428e
String: Password
Array: [C@5829428e

回答3

引用官方的文Java加密体系结构指南说到char[] vs String。在对象java.lang.String中收集和存储密码看似符合逻辑,但是字符串对象是不可变的,没有任何方法可以改变(重写)或清空内容。这一特性使得字符串对象不适合存储安全敏感信息,比如用户密码。你应当使用一个字符数组来代替,以便收集和存储安全敏感的信息。安全编码指南4.0也提到了类似的问题。

回答4

char[])在使用之后里面的元素可以被清除,字符串并不如此。如果有人能以某种方式看到内存映像,如果字符串被使用了,它们可以以纯文本方式看到密码。但如果是char[], 看到的是清除后的数据(用0替换的数据),这种方式是安全的。

最后的思考

char[]并不能保证足够安全,但我也建议使用hash’d或者加密的密码来代替普通的文本字符串密码,而且使用完后立即清除。