I'm writing software for the JVM (in Clojure) that performs a cryptographic operation. Specifically, given a secret input, secret key, non-secret salt, non-secret personalization, it uses BLAKE2 to derive 512 bits of key material. It then chops up that array into two 256 bit chunks, using tools from the Arrays
class. (source)
The actual implementation of that operation lives in libsodium so it's implemented in C. I'm using caesium to access it, which is a wrapper over kalium, a library that uses jnr-ffi to call the underlying C implementation.
Since all of the buffers above have sensitive key material, I'd like to make sure it's purged from memory. I'm not sure how to do that safely on the JVM (heck, I'm not even sure I know how to do that safely in C). Given that the material is translated from C const char *
to JVM byte[]
, and then some of my operations make new JVM byte arrays, key material is going to live in JVM byte arrays. That raises two concerns:
byte[]
, which is not touched by any code afterwards, how can I be sure the byte[]
was actually zeroed out? I'd assume the JVM is free to optimize that away.byte[]
gets zeroed out, how do I know the JVM hasn't decided to copy that array (e.g. in the context of a garbage collector) plenty of times without zeroing out the original location, hence leaving the keying material all over virtual memory anyway?I'm guessing the answer will end up being "do it in C & ASM" or maybe even "do it in a HSM", but I'd love to hear if there are JVM-land ways of fixing this problem.
If all you need is to clean an array, Arrays.fill does not allocate a new array but changes the values in the one passed as parameter. If you download the sources you can read it directly there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With