1

In Java, When having objects that you need to securely dispose of, which are the options?

Taking into account that:

a) The when: You need some guarantee on when the object is disposed. Is calling System.gc() the only/better option?

b) The how: GC is not enough and you need to make sure the memory an object instance is using is properly erased. One can first get references to the internal object representation via reflection (get char[] inside a String) and overwrite the data. However, this method requires an implementation for each type of object.

Are there better ways to make sure that passwords and private key objects are not left on RAM?

Update: Passwords are an example. This question focuses on general methods for object secure destruction. Think BigInteger, PGPPrivateKey, RSAWhatever, etc.

  • @SLaks No, what if I have a cryptographic object from FooLib that I can't replace with a `byte[]` because I'm going to need to wrap it in an object anyway? This isn't really a duplicate. – nanofarad Sep 09 '13 at 15:11
  • 2
    I'd just like to point out that GC is VM-specific. Calling System.gc() gives no guarantees that the garbage collector will free all memory that isn't referenced. –  Sep 09 '13 at 15:12
  • 1
    Also GC just "frees memory to be used again by something else" it doesn't overwrite it so anything in that memory location is going to still be there until it gets re-allocated and overwritten, which may be never. –  Sep 09 '13 at 15:15
  • @slaks, I've clarified the question. It is clearly not a duplicate. How can I unmark it? – pau.minoves Sep 12 '13 at 09:58

3 Answers3

2

Disclaimer: This uses reflection and may not be the nicest way.

However, this method requires an implementation for each type of object.

No, not really. You can iterate through fields and destroy those, or even traverse an entire object graph. The first step to go would be primitives and arrays of primitives, and nulling out object references that are fields of the object you are trying to "shred". In fact, that last step could be done recursively with a null-check.

nanofarad
  • 40,330
  • 4
  • 86
  • 117
  • Isn't it safer to replace the data in a password `char[]` then `null`ing the reference? – Sotirios Delimanolis Sep 09 '13 at 15:12
  • 2
    I don't see how nulling references does anything at all to securely remove the item from memory. – T.J. Crowder Sep 09 '13 at 15:13
  • @SotiriosDelimanolis Covered in "arrays of primitives". You're assuming the OP can simply change their implementation to use a char array instead of a string. If a crypto library requires an object that wraps a key and other parameters, you're not going to have much luck there. – nanofarad Sep 09 '13 at 15:13
  • In OP's example, `null`ing the `String` reference is therefore equivalent to what you are proposing. – Sotirios Delimanolis Sep 09 '13 at 15:14
  • @T.J.Crowder I'm probably not being clear in my post, but I don't know how to clarify. If I'm looking at something like a string, except where I don't know too much about it, then reflectively I'd seek to destroy arrays of primitives, primitives, and then at least null out references my cleanup code doesn't understand. – nanofarad Sep 09 '13 at 15:15
  • @SotiriosDelimanolis No, I'm proposing to, in an unknown object(let's say it has an `int`, a `char[]`, and another object) to zero the int, clear the char array, and set that other object itself to null since I don't know what to do with it without traversing the object graph. – nanofarad Sep 09 '13 at 15:16
  • @hexafraction Ok, that makes more sense. You can always call the deletion method recursively on reference type fields. – Sotirios Delimanolis Sep 09 '13 at 15:23
  • The problem with this solution is that it is dangerous how references can lead to actual data that you don't want to delete. Maybe using a special @Annotation to mark fields that you want to delete and when to stop crawling could be good. – pau.minoves Sep 09 '13 at 16:05
2

I would use off heap memory so it won't appear in any heap dump, and won't be copied around (even if you clear char[] an old copy could still be readable) Once you overwrite it you know where won't be another copy somewhere.

Off heap memory is harder to work with as you have to deal in primitives, but it is easy to zero out as you can just overwrite everything in it.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • Please, can you extend on "use off heap memory"? – pau.minoves Sep 09 '13 at 15:56
  • You can use ByteBuffer.allocateDirect() or Unsafe, or one of the libraries which now supports off heap memory. – Peter Lawrey Sep 09 '13 at 16:01
  • Thanks for the explanation. +1 for avoiding the "copy around" but still, a regular memory dump or "cat /dev/mem" will reveal the object contents. Am I right? – pau.minoves Sep 09 '13 at 16:26
  • @pau.minoves if someone has that kind of access to the machine, is there anything you can do to stop them? – corsiKa Sep 09 '13 at 16:28
  • @pau.minoves Assuming you let someone have access to the memory, yes. But then again it would be simpler for them to change the code to log all the passwords. – Peter Lawrey Sep 09 '13 at 16:28
  • The idea is to limit from code the window of time while the secret data is in memory. Somebody could have access to your computer after your program has finished (think public PCs, not servers) or another program might be given a memory page you have used. – pau.minoves Sep 12 '13 at 10:00
  • @pau.minoves I wouldn't put important passwords in a PC. Only those passwords the user should know already. – Peter Lawrey Sep 12 '13 at 10:09
1

You can't rely on garbage collection to remove your object from memory; calling System.gc() doesn't cause gc to run - it just "asks nicely". It could hang around for a while in memory.

The standard approach is to use an object that can be wiped before disposal, like char[] instead of String:

char[] password = <read password from input stream etc>
// check password
Arrays.fill(password, 'x');
// password available for gc, but now wiped

This only reduces the time that the password is in memory. It doesn't eliminate it. If someone got a memory dump at the right time they may be able to find the bytes. If you secure your server well, getting the dump should be difficult to impossible in the first place.

Bohemian
  • 412,405
  • 93
  • 575
  • 722