Is the following java code sufficient for clearing the secret key in memory (setting all of its byte value to 0)?
zerorize(SecretKey key)
{
byte[] rawKey
Depending on the technology powering the garbage collector, any single object may be moved (i.e. copied) in physical memory at any time, so you cannot be sure that you will really destroy the key by zeroing an array -- assuming that you can access "the" array which holds the key, and not a copy thereof.
In shorter words: if your security model and context call for zeroing keys, then you should not use Java at all (or just about anything but C and assembly).
getEncoded()
seems to mostly return a clone of the key (from the Oracle 1.6 source of for instance javax.security.auth.kerberos
):
public final byte[] getEncoded() {
if (destroyed)
throw new IllegalStateException("This key is no longer valid");
return (byte[])keyBytes.clone();
}
hence wiping the return data does not erase all copies of the key from memory.
The only way to wipe the key from the SecretKey
is to cast it to javax.security.auth.Destroyable
if it implements the interface and invoke the destroy()
method:
public void destroy() throws DestroyFailedException {
if (!destroyed) {
destroyed = true;
Arrays.fill(keyBytes, (byte) 0);
}
}
Strangely enough it seems that all Key implementation do not implement javax.security.auth.Destroyable
. com.sun.crypto.provider.DESedeKey
does not nor does javax.crypto.spec.SecretKeySpec
used for AES. Both of these key implementations also clone the key in the getEncoded
method. So it seems for these very common algorithms 3DES and AES we don't have a way to wipe the memory for the secret key?