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