36

I never thought before, only I used the method getPassword that returning an array of characters and I had seen the getText method was deprecated. But now that I think, why this method was deprecated?.

The Java documentation explains:

Deprecated. As of Java 2 platform v1.2, replaced by getPassword.

Fetches a portion of the text represented by the component. Returns an empty string if length is 0.

For security reasons, this method is deprecated. Use the getPassword method instead.

But what are those security reasons? Any ideas about this?

Thank you in advance.

Paul Vargas
  • 41,222
  • 15
  • 102
  • 148
  • 2
    http://stackoverflow.com/questions/983964/why-does-jpasswordfield-getpassword-create-a-string-with-the-password-in-it – Garbage May 04 '12 at 05:52

5 Answers5

60

When calling getText you get a String (immutable object) that may not be changed (except reflection) and so the password stays in the memory until garbage collected.

When calling getPassword you get a char array that may be modified, so the password will really not stay in memory.

MByD
  • 135,866
  • 28
  • 264
  • 277
29

Try this :

String myPass=String.valueOf(passwordField.getPassword());
Karup
  • 2,024
  • 3
  • 22
  • 48
John Cableur
  • 309
  • 3
  • 3
  • 3
    The OP is not asking *how to get the password as a `String`*; he is asking *why the password is returned as a `CharrArray` instead of a `String`. – Barranka Jul 02 '15 at 23:02
9

The reason for this is that if you ask for the password as a String rather than as a character array, this string containing the password is now going to float around in the Java runtime's memory for some unspecified amount of time. It may be conceivably read from there by a rogue Java component or external program.

By using a char array instead, you can verify the password and then scramble it immediately.

Zarkonnen
  • 22,200
  • 14
  • 65
  • 81
5

The reason behind this behavior is the Java String pool (see e.g. this SO question for more info). As soon as you convert the contents of that password field to a String (which is what happens if you use the getText method) the String is placed in the pool, and can be read by others.

If you would look at the implementation of the getPassword method (as can be seen in the SO question @Garbage posted as a comment on your question) you can see this carefully avoids creating a String.

Note that this also means you should not do something like

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

or you still end up with putting the password in the pool, and then you could as easily have used the getText method.

Community
  • 1
  • 1
Robin
  • 36,233
  • 5
  • 47
  • 99
  • The "Java string pool" is for intern'ed constants at compile time.. I question whether a standard Swing text-input *really* interns text values entered into it. My understanding would be that returning a char[] array rather than immutable String allows the password to be zeroed out immediately to minimize exposure/visibility in working memory (security best practice). The String would never be expected to be `intern`ed either way. – Thomas W Sep 17 '13 at 03:21
0
  • getText () returns a String, so that String is added (as standard Java behavior) to the pool of Strings. The Pool of Strings is cleaned by the Garbage Collector, but only when it acts (and it cannot be on demand). Thus, a password can remain in the pool even if it is not wanted, and it can be read by some other Java process.

  • getPassword () returns an array of chars. These are not Strings, but array objects, so although they are also deleted when the Garbage Collector wants, they do not remain in any pool and are inaccessible by other java processes.

But you have to be careful with how you use the array of chars read by getPassword (), because if we convert it to a String, then it goes to the pool and it is just as bad as if we had used getText () ...

JYOC
  • 1
  • 2