Java 使用PrivateKey数据后如何从内存中清除它?

Java 使用PrivateKey数据后如何从内存中清除它?,java,cryptography,rsa,private-key,Java,Cryptography,Rsa,Private Key,有没有办法从内存中删除私钥中的敏感信息?(不希望垃圾收集器清理?) 我是否必须编写自己的PrivateKey 或 有什么我可以使用的吗?您必须确保没有任何敏感数据被放入不可变的数据类型(例如,您不能使用字符串),因为当您处理完敏感数据时,您需要能够覆盖它 您可能会将私钥的内容保存在字节数组中(因为这正是getEncoded()返回的内容)。当您使用完私钥后,用零(或其他什么)填充字节数组 您可能需要实现自己版本的PrivateKey,因此可以添加此新功能(因为您无法保证提供的实现将别名返回到实际

有没有办法从内存中删除私钥中的敏感信息?(不希望垃圾收集器清理?)

我是否必须编写自己的
PrivateKey



有什么我可以使用的吗?

您必须确保没有任何敏感数据被放入不可变的数据类型(例如,您不能使用字符串),因为当您处理完敏感数据时,您需要能够覆盖它

您可能会将私钥的内容保存在字节数组中(因为这正是
getEncoded()
返回的内容)。当您使用完私钥后,用零(或其他什么)填充字节数组

您可能需要实现自己版本的PrivateKey,因此可以添加此新功能(因为您无法保证提供的实现将别名返回到实际阵列而不是副本)


您还需要担心
getEncoded()
的任何调用者,因为调用者可以保留数据的副本。

在常规Java中,如果不使用本机,就无法做到这一点。JVM总是可以复制数据,并且
RSAPrivateKey
接口指定
getPrivateExponent()
返回一个不可变的
bitineger
实例。这由
密码
签名
类使用。使用安全令牌(例如使用Sun PKCS#11提供程序)是最好的方法


无论你做什么,如果你认为内存不能保持安全,那么使用解密或登录软件都会有严重的问题。您至少需要操作系统级别的支持,而Oracle Java实现中并没有启用这种支持。

如果您没有对它的引用,为什么您认为您必须担心它在内存中?这只是为了增强应用程序的安全性。当GC没有在删除对PrivateKey的所有引用之后运行时,仍然可以读取/转储内存并检索PrivateKey。但是,如果我能确保在使用后覆盖此数据,则将此风险降至从解密私钥到使用私钥的时间范围内。而不是从解密到将来GC认为可以清理的某个时候要做好这件事相当困难。GC可能会在您的对象周围进行复制或复制,它可能会被交换到SSD(从那里您无法删除它),它可能最终会崩溃转储,…似乎我真的必须实现自己的私钥:(谢谢你的回答。是的,但至少是一个非常简单的接口,所以不会太糟糕。该死,一定是在睡觉。这个方案不起作用。密码和签名的Java实现必须检索私有指数,它作为不可变整数返回。游戏结束,除非你还实现了
密码
签名
安全(使用单独的接口)。即使如此,JVM也可以复制内存,留下一个跟踪。