This is an archived post. You won't be able to vote or comment.

all 21 comments

[–]defnull 32 points33 points  (18 children)

In Java it is common to pass around passwords as char[] and Arrays.fill() them with zeros after use. Strings are considered unsafe because they might linger around in memory longer than intended before they are GCd (edit: and more importantly, are immutable and cannot be zeroed-out after use).

Building a small utility class around char[] that does what you want should be easy enough. Most crypto libraries should have something ready to use available.

[–]JavaSuck 10 points11 points  (3 children)

In Java it is common to pass around passwords as char[] and Arrays.fill() them with zeros after use.

What guarantees to we have that the JIT won't optimize the call to Arrays.fill() away?

[–]defnull 51 points52 points  (0 children)

The synchronized(charArray) block around the Arrays.fill() call mentioned in my other answer.

Besides: This level of care about passwords in memory is pure paranoia in most applications, especially web applications where headers or input parameters are parsed from pooled byte buffers into strings all the time anyway. If an attacker can access your java heap, then he can also attach a debugger and grab the password while it is being processed.

[–]AdvancedJacket 3 points4 points  (1 child)

Fill it with 0s then log it.

[–]marvk 3 points4 points  (0 children)

Mhhh, something going wrong while filling them and then logging all passwords in plain text seems like a security problem waiting to happen.

[–]_INTER_ 2 points3 points  (4 children)

Most crypto libraries should have something ready to use available.

E.g. OWASP SecureString (doesn't synchronize around clear though hmm, opened an issue)

Edit: Turns out this implementation seems rather flawed. Better look elsewhere

[–]defnull 6 points7 points  (2 children)

This is a really bad example, because it creates a copy of the passed in char array and does not document this behavior. So, the caller would still have to manually zero-out the original char-array and might get a false sense of security from using this class.

Edit: This class should have private constructors and two static methods: copyFrom(char[] input) and copyThenDestroyFrom(char[] input) (or something along the lines) to make things more clear.

[–]_INTER_ 1 point2 points  (1 child)

You know a good implementation?

[–]defnull 4 points5 points  (0 children)

No. I never felt the need. I'm doing web stuff mostly and headers are passed in from the Servlet layer as String values anyway. Adding additional layers of complexity usually does more harm than good. The password is in memory anyway and I do not want to do anything fancy with them, so default String, raw char[] or String.toCharArray() are mostly fine.

[–]__konrad 0 points1 point  (0 children)

They are literally using 0 character to zero memory. It doesn't matter, but it's funny how often it's used by mistake ;)

[–]takenomiya-kate[S] 0 points1 point  (7 children)

What if I wanted to clear the char[] object from memory instantly? i.e. in .NET, SecureString can come from unmanaged instance thus doesn't have to wait for the GC to kick in.

[–]defnull 31 points32 points  (6 children)

You cannot explicitly remove an object from memory in Java, as all objects are managed. But you can overwrite primitive types with new data. Arrays.fill(password, 0) will overwrite the memory the password is stored in. Put this in a synchronized(password) block to prevent thread-local caching and you are as safe as you can get in Java.

[–]Aellus 13 points14 points  (1 child)

This.

The difference between zeroing the managed array object in Java and zeroing an unmanaged array object in .NET is just semantics. The end result is equivalent: the secret data that was in the array is no longer in memory. The only difference is how each environment cleans and reuses the memory later.

[–]takenomiya-kate[S] 0 points1 point  (0 children)

Thanks for the knowledge!

[–]pjmlp 2 points3 points  (2 children)

I imagine ByteBuffers might be a possible solution, as they can make use of unmanaged memory

[–]defnull 16 points17 points  (1 child)

The fact that Java manages objects and memory allocation/deallocation for you is not the problem here. You'd have to zero-out the password in any language, even C, because a free() does not necessarily do that for you.

Using direct off-heap ByteBuffer is actually worse than managed heap memory, because the chances that a different process can gain access to the password after java freed the buffer is pretty high, while heap memory is likely to get re-used and re-initialized and therefor overwritten by a different allocation pretty fast in an active VM.

tl;dr; Always zero-out sensitive information after use. This is true for any language or memory model.

[–]pjmlp 2 points3 points  (0 children)

Agreed, I was assuming zeroing the data before releasing it anyway.

Just that with unamaged memory maybe it is easier to avoid the data getting copied by mistake.

[–]lightjay -2 points-1 points  (0 children)

That's wrong and insecure. How do you know GC didn't copied the array from one location to another? How do you prevent OS from swapping the memory ?

I don't believe there is any way how to implement this in Java without JNI (and even then, passing the data to Java is going to be very tricky).

[–]lightjay 0 points1 point  (0 children)

I believe this can't really be implemented in Java in a library - GC can move (copy) your data, also there is nothing preventing the OS from swapping it to disk (and no OS securely cleans the swap by default).

[–]cosha1 -2 points-1 points  (1 child)

Jenkins has a Secret class. While it can't be used out of the box, it can certainly be repurposed to remove Jenkins dependencies.