【问题标题】:how to 'Zero out' from memory an AES SecretKeySpec Key in Java如何从内存中“清零”Java 中的 AES SecretKeySpec 密钥
【发布时间】:2015-03-07 05:20:01
【问题描述】:

我正在使用 Java AES 加密

SecretKeySpec(byte[] key, String algorithm) 

生成一个 Key 对象。

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

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

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

【问题讨论】:

  • AFAIK,没有办法显式告诉 java 的 GC 清理特定对象,也没有办法显式调用它。您只能通过请求完成来提供提示。我想您可以通过调整 GC 的激进程度来减少它在内存中可能花费的时间,但除此之外,我认为这是不可能的。这是一篇关于 GC 调优的博文,可能会有所帮助:cubrid.org/blog/dev-platform/…
  • @MarkW,垃圾收集无论如何都不会清零关键材料。它只会使该内存可供可能以后重新使用。事实上,即使有一个方法可以将 Key 对象归零,GC 仍然是个问题,因为它可能在调用 zeroize 方法之前就已经移动了对象,这样会在旧版本中留下密钥材料的副本位置。
  • @jameslarge 同意...我怀疑唯一的方法可能是用一些任意值实际填充可用内存,然后立即进行 GC,但这是一个可怕的解决方案。我将不得不关注这个问题,看看是否有其他人知道实现它的真正方法。
  • 在构造函数中使用 byte[] 的目的似乎是用于生成密钥的对象可以归零,但是密钥仍然在内存中浮动。我不想在之后再调用 GC,因为那不会保证任何东西,而且会很慢。

标签: java memory encryption aes symmetric-key


【解决方案1】:

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

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

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

但是,请注意 cmets:

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

还要注意,将原始字节数组清零不会清除 SecretKeySpec,因为它需要字节数组 in its constructor 的副本。

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

【讨论】:

  • destroyable 接口只会让对象在destroy() 之后无法被调用,对吧?它不会影响内存中对象的实际“内容”。如果执行内存转储,即使对象被destroy(),仍然可以获得Key的内容,对吧?
  • 应该清除字节数组:JavaDoc 说“与此对象关联的敏感信息已被销毁或清除。随后调用此对象上的某些方法将导致 IllegalStateException被抛出” ...和“实现应该覆盖 Destroyable 接口中的默认销毁和 isDestroyed 方法,以使敏感的关键信息能够被销毁、清除,或者在此类信息不可变的情况下,不被引用。”
  • 我认为你在这里是正确的。好的!猜猜是时候升级到 Java 8 了!
【解决方案2】:

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

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

【讨论】:

  • 它没有解决 GC 移动它的问题,独立的线程堆栈已经复制,或者虚拟内存,对吧?
  • 是的。我更想了解 Java 可能不是这项工作的语言这一原则。也许我有点太具体了,在这一点上出现了这些问题。我会编辑。
猜你喜欢
  • 1970-01-01
  • 2015-01-19
  • 2015-08-13
  • 1970-01-01
  • 2019-08-04
  • 2018-05-31
  • 2011-11-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多