Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Irretrievably destroying data in Java

Tags:

java

security

Is there anyway in Java to delete data (e.g., a variable value, object) and be sure it can't be recovered from memory? Does assigning null to a variable in Java delete the value from memory? Any ideas? Answers applicable to other languages are also acceptable.

like image 853
BlueGene Avatar asked Sep 23 '08 11:09

BlueGene


2 Answers

Due to the wonders virtual memory, it is nearly impossible to delete something from memory in a completely irretrievable manner. Your best bet is to zero out the value fields; however:

  • This does not mean that an old (unzeroed) copy of the object won't be left on an unused swap page, which could persist across reboots.
  • Neither does it stop someone from attaching a debugger to your application and poking around before the object gets zeroed or crashing the VM and poking around in the heap dump.
like image 152
Aaron Maenpaa Avatar answered Oct 06 '22 00:10

Aaron Maenpaa


Store sensitive data in an array, then "zero" it out as soon as possible.

Any data in RAM can be copied to the disk by a virtual memory system. Data in RAM (or a core dump) can also be inspected by debugging tools. To minimize the chance of this happening, you should strive for the following

  • keep the time window a secret is present in memory as short as possible
  • be careful about IO pipelines (e.g., BufferedInputStream) that internally buffer data
  • keep the references to the secret on the stack and out of the heap
  • don't use immutable types, like String, to hold secrets

The cryptographic APIs in Java use this approach, and any APIs you create should support it too. For example, KeyStore.load allows a caller to clear a password char[], and when the call completes, as does the KeySpec for password-based encryption.

Ideally, you would use a finally block to zero the array, like this:

KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream is = …
char[] pw = System.console().readPassword();
try {
 ks.load(is, pw);
}
finally {
  Arrays.fill(pw, '\0');
}
like image 35
erickson Avatar answered Oct 05 '22 23:10

erickson