36

我以前从未想过,只是我使用了getPassword返回字符数组的方法,并且我看到该getText方法已弃用。但现在我想,为什么这种方法被弃用了?

Java 文档解释:

已弃用从 Java 2 平台 v1.2 开始,由getPassword.

获取由组件表示的文本的一部分。如果长度为 0,则返回一个空字符串。

出于安全原因,不推荐使用此方法。请改用该getPassword方法。

但是这些安全原因是什么?有什么想法吗?

先感谢您。

4

5 回答 5

56

调用时getText,您会得到一个可能不会更改(反射除外)的字符串(不可变对象),因此密码将保留在内存中,直到垃圾收集。

调用时getPassword您会得到一个可能被修改的 char 数组,因此密码实际上不会留在内存中。

于 2012-05-04T05:52:50.647 回答
27

试试这个 :

String myPass=String.valueOf(passwordField.getPassword());
于 2015-07-02T22:01:27.733 回答
9

这样做的原因是,如果您以字符串而不是字符数组的形式请求密码,则包含密码的字符串现在将在 Java 运行时的内存中浮动一段未指定的时间。它可能会被恶意 Java 组件或外部程序从那里读取。

通过使用 char 数组,您可以验证密码,然后立即对其进行加扰。

于 2012-05-04T05:53:17.007 回答
5

这种行为背后的原因是 Java 字符串池(有关更多信息,请参见例如这个 SO 问题)。一旦您将该密码字段的内容转换为 a String(如果您使用该getText方法会发生这种情况) ,该密码就会String被放入池中,并且可以被其他人读取。

如果您查看该getPassword方法的实现(如作为对您的问题的评论发布的SO 问题@Garbage 中所见),您可以仔细地看到这避免了创建String.

请注意,这也意味着您不应该做类似的事情

if ( Arrays.equals( "mySuperSecretPassword".toCharArray(), passwordField.getPassword() ) )

或者您仍然将密码放入池中,然后您可以轻松使用该getText方法。

于 2012-05-04T06:16:13.677 回答
0
  • getText() 返回一个字符串,以便将字符串(作为标准 Java 行为)添加到字符串池中。字符串池由垃圾收集器清理,但仅在它起作用时(并且不能按需)。因此,即使不需要密码,密码也可以保留在池中,并且可以由其他 Java 进程读取。

  • getPassword() 返回一个字符数组。这些不是字符串,而是数组对象,因此尽管垃圾收集器需要时也会将它们删除,但它们不会保留在任何池中,并且其他 java 进程无法访问它们。

但是你必须小心你如何使用 getPassword() 读取的字符数组,因为如果我们将它转​​换为字符串,那么它会进入池,就像我们使用 getText() 一样糟糕。 ..

于 2021-08-09T09:27:39.050 回答