2

I am writing an application in java that I care about being secure. After encrypting a byte array, I want to forcibly remove from memory anything potentially dangerous such as the key used. In the following snippet key is a byte[], as is data.

SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
byte[] encData = cipher.doFinal(data, 0, data.length);
Arrays.fill(key, (byte)0);

As far as I understand, the last line above overwrites the key with 0s so that it no longer contains any dangerous data, but I can't find a way to overwrite or evict secretKeySpec or cipher similarly.

Is there any way to forcibly overwrite the memory held by secretKeySpec and cipher, so that if someone were to be able to view the current memory state (say, via a cold boot attack), they would not get access to this information?

Bhesh Gurung
  • 50,430
  • 22
  • 93
  • 142
MBennett
  • 451
  • 2
  • 10
  • Filling `key` with 0s will fill 0s in address(es) allocated in memory for the variable- `key`. Looks like that achieves what you are looking for. – ring bearer Mar 24 '12 at 23:28
  • Yep; you will notice I already included such functionality for key. The problem is that secretKeySpec and cipher both contain dangerous data as well, and I don't know of a way to similarly 0 them out. – MBennett Mar 24 '12 at 23:30
  • 1
    0-ing out won't make it completely secure for two reasons pointed out in this SO answer http://stackoverflow.com/questions/120380/irretrievably-destroying-data-in-java – Ozzy Mar 25 '12 at 00:07
  • Zero-fill is the almost perfect thing possible, I think. and @MBennett, What I mean by my comment is that the other objects would not be useful without knowing the key - Don't you think? – ring bearer Mar 25 '12 at 00:15
  • Unfortunately for me, SecretKeySpec does a deep copy of key on construction (which is actually a good thing in general). Thus after zeroing out key it does not zero out the copy that SecretKeySpec has. I forgot to mention that this will be running on Android, and the use case I care about is someone accessing the phone after this code has been run and then determining the key (a new one is generated each time), so the debugger case is not a worry --an excellent answer and helpful though. – MBennett Mar 25 '12 at 00:20
  • 1
    I think there are some good answers to this question in this post: http://security.stackexchange.com/questions/6753/deleting-a-java-object-securely – Ozzy Mar 25 '12 at 00:22
  • If the those variables you are trying to zeroing are local to a method they will cease to exist when the method returns so, we don't gain much in zeroing them. – Zecas May 11 '12 at 14:28
  • Zecas, the variables will cease to exist, but their contents will not be wiped from memory. Just because a local variable goes out of scope does not mean that memory that contained that information is immediately overwritten. – MBennett May 11 '12 at 17:35

1 Answers1

0

You want to do the moral equivalent of old C:

bzero( static_cast<char>(secretKeySpec), sizeof(SecretKeySpec) )

In modern C, memset.

(assuming its a fixed size object known at compile time).

If Java doesn't provide the facility, link to native code in C, C++, or assembly.

Ditto cipher.

Warning: may violate data structure properties, such as breaking a finalize. Also, assumes that the object is contiguous, not a linked data structure.

Krazy Glew
  • 7,210
  • 2
  • 49
  • 62