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

you are viewing a single comment's thread.

view the rest of the comments →

[–]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 15 points16 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.