qbd*_*qbd 3 java security cryptography
当您在Java应用程序中使用敏感数据时,通常建议您使用原始类型-例如,使用char []代替String ...
但是,对于加密密钥,我们通常需要使用java.security.Key对象,因为这是JCE提供程序使用的对象。密钥通常是非常敏感的信息,我们希望能够最小化可能的攻击窗口-即,尽可能晚地创建Key对象,进行加密/解密/签名,然后尽快清除对象。但是Key没有提供任何有助于这种清除的方法。
当前,我们的方式是将密钥保留在字节数组中,并在使用它之前立即初始化Key对象,Key立即超出范围,可以进行垃圾回收,并且我们还立即清除字节数组。但这似乎并不十分优雅……它还会在我们的界面中造成二分法-有些接受字节数组,有些接受Key对象,这有点混乱。
我知道Java没有提供任何通用机制来从内存中清除对象的事实,但是我在问是否有专门针对Keys的东西。或者,是否有其他方法可以最小化密钥的攻击窗口?
谢谢。
升级到Java 8中SecretKey和RSAPrivateKey器具Destroyable。但是,快速测试表明,这不适用于本地生成的AES密钥或RSA私钥。
以下代码可以正常工作,但是仅在第二次初始化(!)之后才会失败,因此请注意,可能会缓存密钥信息(AES要求派生子密钥,因此子密钥可能会持续存在)。使用后,最好使用单独的(零)密钥重新初始化任何密码。此外,它不能防止VM本身复制数据,例如在垃圾回收后的内存压缩期间。
MyAESKey myAESKey = new MyAESKey(new byte[16]);
Cipher aes = Cipher.getInstance("AES");
aes.init(Cipher.ENCRYPT_MODE, myAESKey);
aes.doFinal("owlstead".getBytes());
myAESKey.destroy();
aes.doFinal("owlstead".getBytes());
aes.init(Cipher.ENCRYPT_MODE, myAESKey);
aes.doFinal("owlstead".getBytes());
Run Code Online (Sandbox Code Playgroud)
在哪里MyAESKey实现SecretKey和Destroyable。但是不要忘记销毁输入MyAESKey。您当然可以MyDestroyable对Java 7及更低版本的接口使用类似的方法。
我知道的唯一其他方法是使用使用安全令牌(HSM / TPM /智能卡等)的提供程序,而密钥不会离开设备。在那种情况下,密钥也可能不会被销毁,但至少不可用。
使用本机代码(使用正确的内存类型)的提供程序也可能允许破坏关键数据。但是,即使在VM外部,也可能很难确保关键数据没有留在RAM或(交换)磁盘中的任何位置。
| 归档时间: |
|
| 查看次数: |
1205 次 |
| 最近记录: |