Java JPasswordField.getPassword()的安全原因是什么?

Java JPasswordField.getPassword()的安全原因是什么?,java,security,swing,passwords,jpasswordfield,Java,Security,Swing,Passwords,Jpasswordfield,自Java 1.2以来,JPasswordField.getText()因“安全原因”而被弃用,这使得getPassword()方法的使用更加安全 但是,通过分析堆转储(JPasswordField实例->model->s->array),我能够至少在Oracle JRE 1.7中获得存储在JPasswordField中的密码 那么JPasswordField.getPassword()如何帮助保护密码呢?那么,for it声明: 为增强安全性,建议在使用后通过将每个字符设置为零来清除返回的字符

自Java 1.2以来,
JPasswordField.getText()
因“安全原因”而被弃用,这使得
getPassword()
方法的使用更加安全

但是,通过分析堆转储(
JPasswordField实例->model->s->array
),我能够至少在Oracle JRE 1.7中获得存储在
JPasswordField
中的密码

那么
JPasswordField.getPassword()
如何帮助保护密码呢?

那么,for it声明:

为增强安全性,建议在使用后通过将每个字符设置为零来清除返回的字符数组


但是,当然,如果您使用
getText
方法,您会得到一个不可变的字符串,因此您无法执行相同的建议。

安全注意,尽管getPassword()在内部使用getText()

尽管JPasswordField类继承了getText方法,但是 应改为使用getPassword方法。不仅是getText更少 安全,但将来它可能会返回可见字符串(用于 例如,“***”),而不是键入的字符串

为了进一步增强安全性,一旦您完成角色 getPassword方法返回的数组,应设置其 元素为零


答案很简单。下面是一个实用的方法,解释了
getPassword()
getText()

输出

I am a password
[C@1e4a47e
getPassword()
方法将密码返回为
char[]
,而
getText()
将密码返回为纯文本,即以
字符串的形式

但是,如果你这样打印

System.out.println(new String(jt.getPassword()));
这相当于
JPasswordField
中的
getText()
。但是,这并不意味着
getPassword()
在内部使用
getText()
,然后将其转换为
char
数组

getPassword()
方法使用非字符串API,即
。但是,
也是不可变的,但是
getPassword()
方法从
中获取字符数组并返回它


然而,由于
String
是不可变的,而
char[]
不是不可变的,因此
char[]
被认为是非常安全的,因为它可以被清除。

JPasswordField
本身中仍然存储着一个char数组,所以何必麻烦呢?可以立即清除字符数组。
String
可以在将来某个不确定的时间进行垃圾收集。你的意思是,我需要在使用?@FrozenSpider后立即清除JPasswordField内容-这是建议。我现在无法检查-通过
getPassword
返回的数组是您正在查看的内部数组,还是副本?@Damien\u非信徒返回的数组是通过
系统创建的副本。arraycopy(…)
,因此我们似乎需要同时清除这两个数组-一个直接清除,另一个通过
setText(null)清除
。谢谢您的拷贝粘贴,是的。无论如何,这不是一个答案,请看我对@Damien_不信者的答案的评论。@FrozenSpider更改了答案-
System.out.println(new String(jt.getPassword()));