我正在为执行加密操作的JVM(在Clojure中)编写软件。具体地,给定秘密输入,秘密密钥,非秘密盐,非秘密个性化,它使用BLAKE2来导出512位密钥材料。然后,它使用Arrays
类中的工具将该数组切换为两个256位块。 (source)
该操作的实际实现存在于libsodium中,因此它在C中实现。我正在使用caesium来访问它,这是kalium的一个包装器,一个使用的库jnr-ffi调用底层的C实现。
由于上面的所有缓冲区都有敏感的密钥材料,我想确保它从内存中清除。我不确定如何在JVM上安全地做到这一点(哎呀,我甚至不确定我知道how to do that safely in C)。鉴于材料已从C const char *
转换为JVM byte[]
,然后我的一些操作会生成新的JVM字节数组,因此密钥材料将存在于JVM字节数组中。这引起了两个问题:
byte[]
进行了zerofill,之后没有被任何代码触及,我怎样才能确定byte[]
实际上已归零?我假设JVM可以自由地优化它。byte[]
被清零,我怎么知道JVM还没有决定复制那个数组(例如在垃圾收集器的上下文中)很多次没有清零原始位置,因此无论如何都将密钥材料留在虚拟内存中?我猜这个答案最终会“在C& ASM中做”或者甚至“在HSM中做”,但我很想知道是否有JVM-land方法来解决这个问题问题
答案 0 :(得分:1)
如果只需清理数组,Arrays.fill不会分配新数组,而是更改作为参数传递的值。如果您下载源代码,可以直接在那里阅读。