Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何';归零';从内存中获取Java中的AES SecretKeySpec密钥_Java_Memory_Encryption_Aes_Symmetric Key - Fatal编程技术网

如何';归零';从内存中获取Java中的AES SecretKeySpec密钥

如何';归零';从内存中获取Java中的AES SecretKeySpec密钥,java,memory,encryption,aes,symmetric-key,Java,Memory,Encryption,Aes,Symmetric Key,我使用javaaes加密 SecretKeySpec(byte[] key, String algorithm) 生成一个键对象 加密某些内容后,我想从内存中删除密钥 我可以删除对该键的所有引用,但这不能保证该键不会在内存中的某个位置浮动 我可以“调零”用于生成密钥的byte[]数组,但如何调零或刷新实际的密钥内存。在7之前的Java版本中,似乎没有办法做到这一点,但在Java 8中,它已通过添加可销毁的接口得到修复 看 通过增强java.security.PrivateKey和 javax

我使用javaaes加密

SecretKeySpec(byte[] key, String algorithm) 
生成一个键对象

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

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


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

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

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

但是,请注意以下评论:

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

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


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

如果您无法使用Java 8,您需要有点创造性。也就是说,为作业选择正确的工具。在这种情况下,我建议C.C允许您完全访问实际内存;Java将几乎所有这些都抽象出来。因此,解释如下:

  • 获取对象的内存地址。这可以使用
  • 使用此内存地址,将其传递给C程序。那你就可以了
  • 手动将内存地址归零

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

AFAIK,没有办法显式地告诉java的GC清理特定对象,也没有办法显式地调用它。您只能通过请求完成来提供提示。我想您可以通过调整GC的攻击性来减少它在内存中可能花费的时间,但除此之外,我认为这是不可能的。这里有一篇关于GC调优的博客文章可能会有所帮助:@MarkW,垃圾收集无论如何都不会将关键材料归零。它只会使该内存可供以后重新使用。事实上,即使有一种方法将密钥对象归零,GC仍然是一个问题,因为它可能在调用归零方法之前移动了对象,这将在旧位置留下密钥材料的副本。@jameslarge同意。。。我怀疑唯一的方法可能是用一些任意值填充可用内存,然后立即进行GCD,但这是一个可怕的解决方案。我必须遵循这个问题,看看是否有其他人知道实现它的真正方法。似乎在构造函数中使用byte[]的意义在于,用于生成密钥的对象可以归零,但密钥仍然在内存中浮动。我不希望事后必须校准GC,因为这样做不会保证任何事情,而且速度会很慢。请参阅,它也不能解决GC移动、独立线程堆栈复制或虚拟内存的问题,对吗?是的。我更多的是试图理解一个原则,即Java可能不是适合这份工作的语言。也许我说得有点太具体了,在这一点上,这些问题就出现了。我会编辑。destroyable接口只会使对象在destroy()之后无法调用,对吗?它不会影响内存中对象的实际“内容”。如果执行内存转储,即使对象已销毁(),也可以获取密钥的内容,对吗?它应该清除字节数组:表示“与此对象相关的敏感信息已销毁或清除。对此对象的某些方法的后续调用将导致引发非法状态异常”。。。“实现应该覆盖可销毁接口中的默认销毁和isDestroyed方法,以便销毁、清除敏感密钥信息,或者在这些信息不可变、未引用的情况下。”我认为您在这里是正确的。美好的我想是时候升级到Java8了!