简体   繁体   English

如何在JVM上安全地处理和清零密钥材料缓冲区?

[英]How do I securely handle and zero key material buffers on the JVM?

I'm writing software for the JVM (in Clojure) that performs a cryptographic operation. 我正在为执行加密操作的JVM(在Clojure中)编写软件。 Specifically, given a secret input, secret key, non-secret salt, non-secret personalization, it uses BLAKE2 to derive 512 bits of key material. 具体地,给定秘密输入,秘密密钥,非秘密盐,非秘密个性化,它使用BLAKE2来导出512位密钥材料。 It then chops up that array into two 256 bit chunks, using tools from the Arrays class. 然后,它使用Arrays类中的工具将该Arrays为两个256位块。 ( 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. 该操作的实际实现存在于libsodium中,因此它在C中实现。我正在使用cesium来访问它,这是kalium的包装器, kalium是一个使用jnr-ffi来调用底层C实现的库。

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 ). 我不确定如何在JVM上安全地做到这一点(哎呀,我甚至不知道如何在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. 鉴于材料是从C const char *为JVM byte[] ,然后我的一些操作产生新的JVM字节数组,关键材料将存在于JVM字节数组中。 That raises two concerns: 这引起了两个问题:

  • If I zerofill a byte[] , which is not touched by any code afterwards, how can I be sure the byte[] was actually zeroed out? 如果我将一个byte[] zerofill,之后没有被任何代码触及,我怎么能确定byte[]实际上是否被清零了? I'd assume the JVM is free to optimize that away. 我假设JVM可以自由地优化它。
  • Even if I was able to guarantee a byte[] gets zeroed out, how do I know the JVM hasn't decided to copy that array (eg 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? 即使我能够保证byte[]被清零,我怎么知道JVM没有决定复制该数组(例如在垃圾收集器的上下文中)很多次都没有将原始位置归零,因此无论如何,将密钥材料留在虚拟内存中?

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. 我猜测答案将最终成为“在C&ASM中做到”或甚至“在HSM中做”,但我很想知道是否有JVM-land方法来解决这个问题。

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. 如果只需要清理一个数组,Arrays.fill就不会分配一个新数组,而是更改作为参数传递的值。 If you download the sources you can read it directly there. 如果您下载源代码,可以直接在那里阅读。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM