getEncoded() seems to basically return a clone of the key (from an Oracle 1.6 source, e.g. javax.security.auth.kerberos ):
public final byte[] getEncoded() { if (destroyed) throw new IllegalStateException("This key is no longer valid"); return (byte[])keyBytes.clone(); }
therefore, clearing the returned data does not erase all copies of the key from memory.
The only way to erase a key from SecretKey is to pass it to javax.security.auth.Destroyable if it implements the interface and calls the destroy() method:
public void destroy() throws DestroyFailedException { if (!destroyed) { destroyed = true; Arrays.fill(keyBytes, (byte) 0); } }
Oddly enough, it seems that the entire Key implementation does not implement javax.security.auth.Destroyable . com.sun.crypto.provider.DESedeKey does not use javax.crypto.spec.SecretKeySpec for AES. Both of these key implementations also clone the key in the getEncoded method. So, it seems that for these very common 3DES and AES algorithms, we have no way to erase the memory for the private key?
source share