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?
1 Answer 1
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".
8 Comments
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)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.String
from the char[]
before you zero it out...
Arrays.fill(passwd, '0円')
is a better way to zero out an array because it avoids creating a new array.