6

We already know about this suggestion/practice to use char[] instead of String for sensitive data. There is multiple reasons for it. One is to clean up the sensitive data right after they are not needed anymore:

char[] passwd = passwordProvider.getKeyStorePassword();
KeyStore keystore = KeyStore.getInstance("JKS");

// TODO: Create the input stream;
keystore.load(inputstream, passwd);

System.arraycopy(new char[passwd.length], 0, passwd, 0, passwd.length);

// Please continue...

Now the question: does it (i.e. using char[]) make sense (specifically the point mentioned above), when the sensitive data comes to you originally as String value? for example:

char[] passwd = passwordProvider.getKeyStorePassword().toCharArray();
KeyStore keystore = KeyStore.getInstance("JKS");

// TODO: using the passwd, load the keystore;

System.arraycopy(new char[passwd.length], 0, passwd, 0, passwd.length);

// Please continue...

Thanks in advance.

UPDATE2: I'll rephrase the question: in this specific context (forget about changes in future or anything else), does the line "clearing the content of char array" do any good?

UPDATE1: it's not a duplication of Why is char[] preferred over String for passwords? I know what the story is. I'm asking in this specific context, does it still make sense?

Community
  • 1
  • 1
Rad
  • 4,292
  • 8
  • 33
  • 71
  • 2
    Possible duplicate of [Why is char\[\] preferred over String for passwords?](http://stackoverflow.com/questions/8881291/why-is-char-preferred-over-string-for-passwords) – log N Feb 03 '17 at 09:51
  • I think it makes some sense. It's better to have more security shields. Also, it'll ensure that if you ever switch to different password provider, you don't have to change your code. – yeputons Feb 03 '17 at 09:53
  • You're right. But I wanted to learn if it makes sense in this specific context, to which the answer is no, not much. – Rad Feb 04 '17 at 09:29
  • 1
    As a late aside, `Arrays.fill(passwd, '\0')` is a better way to zero out an array because it avoids creating a new array. – Andy Turner Nov 21 '22 at 10:39

1 Answers1

6

It seems to me that it's a security problem in the design of the API of the password provider that it returns a String.

But, if you have to work with that API, converting to char[] immediately means that you aren't preventing the String instance from being GC'd, because you're not holding a reference to it for any longer than is absolutely necessary.

So, it makes sense to use char[] here because you "aren't making it worse".

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • We're close to what I'd like to learn: converting to `char[]` immediately. Does it change anything at low level if I store the result of the `getKeyStorePassword` method in a `String` variable first, and then convert it `char[]`. From what I understand it should not make any different. Is it right? (Assume no changes is allowed anywhere anytime) – Rad Feb 03 '17 at 10:05
  • @Rad invoking `a.b().c()` stores the result of `a.b()` on the stack, and then invokes `c()` on that. This is basically the same as putting it in a variable. The point is that if you have an explicit variable containing that intermediate result, you can - intentionally or otherwise - do something with it that causes it to leak. You can be diligent and carefully scrutinize your code to ensure this doesn't happen, or just not create the variable in the first place, thus not allowing the leakage to occur. – Andy Turner Feb 03 '17 at 10:08
  • Of course, nothing stops you building another `String` from the `char[]` before you zero it out... – Andy Turner Feb 03 '17 at 10:12
  • Got it. thanks. just a clarification: ... stores the result of a.b() on the stack. I think you mean a reference of the result (in heap since it's not primitive) will be stored in the stack. right? – Rad Feb 03 '17 at 10:14
  • Yes, that's what I meant. – Andy Turner Feb 03 '17 at 10:16
  • @Rad BTW, if you can be sure the String is not shared you can clobber the `char[]` of the String, just hacky, but you can do it. If it shared you have a different problem that the String is being retained/cached somewhere. – Peter Lawrey Feb 03 '17 at 10:30
  • @PeterLawrey could you please give more info on how to do it?. I'd like to learn, just in case I had to do :) – Rad Feb 03 '17 at 17:21
  • @Rad You can use reflection to obtain the underlying `char[]` in the field `value` – Peter Lawrey Feb 03 '17 at 17:26