4

我正在使用 Java AES 加密

SecretKeySpec(byte[] key, String algorithm) 

生成一个 Key 对象。

加密某些内容后,我想从内存中删除密钥。

我可以删除对密钥的所有引用,但这并不能保证密钥不会在内存中的某个位置浮动。

我可以将用于生成密钥的 byte[] 数组“清零”,但是如何清零或刷新实际的密钥内存。

4

2 回答 2

4

在 Java 版本 7 之前似乎没有办法做到这一点,但它已通过添加Destroyable接口为 Java 8 修复。

https://bugs.openjdk.java.net/browse/JDK-6263419

通过增强 java.security.PrivateKey 和 javax.crypto.SecretKey 类来扩展 javax.security.auth.Destroyable 接口来满足此要求。

但是,请注意以下评论:

清除 BigInteger 或 byte[] 引用并不能保证敏感信息已从内存中消失。操作系统的虚拟内存可能已交换到磁盘,例如,在本地硬盘驱动器上留下一个副本。此外,Java 运行时 VM 本身可能具有多个内部信息副本。

另请注意,将原始字节数组清零不会清除 SecretKeySpec,因为它在其构造函数中获取字节数组的副本。

但是,您可能能够使用Java 反射更改对该字段的访问权限来访问字节数组的 SecretKeySpec 副本(即使它是私有的) 。

于 2015-03-06T21:14:42.880 回答
3

如果您无法使用 Java 8,那么您将需要一点创意。即,为工作选择正确的工具。在这种情况下,我建议使用 C。C 可以让您完全访问实际内存;Java 将几乎所有这些都从您那里抽象出来。所以解释如下:

正如评论中所指出的,出现了更多的实现级别的细节。这个答案的重点是强调其他语言在这方面做得更好,可能值得研究。

于 2015-03-06T21:19:31.480 回答