我之前从未想过,只有我使用返回字符数组的方法getPassword
,我看到getText
方法已弃用。但现在我认为,为什么这种方法已弃用?。
Java文档说明:
已过时即可。 从Java 2平台v1.2开始,由
getPassword
替换。获取组件表示的部分文本。返回一个 如果长度为0,则为空字符串。
出于安全考虑,这种方法是 弃用。请改用
getPassword
方法。
但那些 安全原因 是什么?有关于此的任何想法吗?
提前谢谢。
答案 0 :(得分:41)
调用getText
时,会得到一个可能无法更改的String(不可变对象)(反射除外),因此密码会保留在内存中,直到收集垃圾。
当调用getPassword
时,你得到一个可能被修改的字符数组,所以密码真的不会留在内存中。
答案 1 :(得分:13)
试试这个:
RESULT:
答案 2 :(得分:8)
这样做的原因是,如果您要求将密码设置为字符串而不是字符数组,则包含密码的字符串现在将在Java运行时的内存中浮动一段时间。可以想象,可以从那里读取流氓Java组件或外部程序。
通过使用char数组,您可以验证密码,然后立即对其进行加密。
答案 3 :(得分:5)
此行为背后的原因是Java字符串池(有关详细信息,请参阅例如this SO question)。只要将该密码字段的内容转换为String
(如果使用getText
方法会发生这种情况),String
就会被放入池中,并且可以读取由其他人。
如果您要查看getPassword
方法的实现(可以在SO question @Garbage中看到,作为对您的问题的评论),您可以看到这一点,小心避免创建{{ 1}}。
请注意,这也意味着您不应该执行类似
的操作String
或者您仍然最终将密码放入池中,然后您可以轻松地使用if ( Arrays.equals( "mySuperSecretPassword".toCharArray(), passwordField.getPassword() ) )
方法。
答案 4 :(得分:0)
getText () 返回一个字符串,以便将字符串添加到字符串池中(作为标准 Java 行为)。字符串池由垃圾收集器清理,但仅在它起作用时(并且不能按需)。因此,即使不需要密码,密码也可以保留在池中,并且可以被其他 Java 进程读取。
getPassword() 返回一个字符数组。这些不是字符串,而是数组对象,所以虽然在垃圾收集器需要的时候也会被删除,但它们不会留在任何池中,其他java进程无法访问。
但是你必须小心你如何使用getPassword()读取的字符数组,因为如果我们将它转换为String,那么它就会进入池中,就像我们使用getText一样糟糕() ...