bar*_*uin 51 java encryption jce aes
使用标准JDK在Java中生成安全随机AES密钥的推荐方法是什么?
在其他帖子中,我发现了这一点,但使用a SecretKeyFactory可能是一个更好的主意:
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
SecureRandom random = new SecureRandom(); // cryptograph. secure random
keyGen.init(random);
SecretKey secretKey = keyGen.generateKey();
Run Code Online (Sandbox Code Playgroud)
如果答案包括解释为什么它是生成随机密钥的好方法,那将是很好的.谢谢!
Dun*_*nes 75
我会使用您建议的代码,但稍作简化:
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256); // for example
SecretKey secretKey = keyGen.generateKey();
Run Code Online (Sandbox Code Playgroud)
让提供者选择计划如何获得随机性 - 不要定义可能不如提供者已经选择的内容.
此代码示例假定(正如Maarten在下面指出的那样)您已将java.security文件配置为在列表顶部包含首选提供程序.如果要手动指定提供程序,只需调用即可KeyGenerator.getInstance("AES", "providerName");.
对于真正安全的密钥,您需要使用硬件安全模块(HSM)来生成和保护密钥.HSM制造商通常会提供一个JCE提供商,使用上面的代码为您完成所有密钥生成.
Maa*_*wes 23
使用KeyGenerator将是首选方法.正如Duncan指出的那样,我肯定会在初始化期间给出密钥大小.KeyFactory是一种应该用于预先存在的密钥的方法.
好的,让我们来看看这个细节.原则上,AES密钥可以具有任何值.在(3)DES中没有"弱键".也没有任何具有特定含义的位,如(3)DES奇偶校验位.因此,生成密钥可以像生成具有随机值的字节数组一样简单,并SecretKeySpec在其周围创建.
但是您使用的方法仍然有优势:KeyGenerator专门用于生成密钥.这意味着代码可以针对这一代进行优化.这可以提高效率和安全性.例如,它可以被编程为避免暴露密钥的定时侧信道攻击.请注意,清除任何byte[]保存密钥信息可能已经是一个好主意,因为它们可能泄漏到交换文件中(尽管如此可能是这种情况).
此外,如上所述,并非所有算法都使用完全随机密钥.因此使用KeyGenerator会更容易切换到其他算法.更现代的密码只接受完全随机密钥; 这被视为超过例如DES的主要好处.
最后,在我的情况下,最重要的原因是,该KeyGenerator方法是在安全令牌(智能卡,TPM,USB令牌或HSM)中处理AES密钥的唯一有效方式.如果您byte[]使用the 创建,SecretKeySpec则密钥必须来自内存.这意味着密钥可以放在安全令牌中,但无论如何密钥都暴露在内存中.通常,安全令牌仅适用于在安全令牌中生成或通过例如智能卡或关键仪式注入的密钥.KeyGenerator可以向提供者提供A ,以便在安全令牌内直接生成密钥.
正如Duncan的回答所示:始终明确指定密钥大小(和任何其他参数).不要依赖于供应商违约,因为这将使它不清楚你的应用程序在做,每个供应商都可能有自己的缺省值.
其他帖子中有很多很好的建议。这是我使用的:
Key key;
SecureRandom rand = new SecureRandom();
KeyGenerator generator = KeyGenerator.getInstance("AES");
generator.init(256, rand);
key = generator.generateKey();
Run Code Online (Sandbox Code Playgroud)
如果您需要另一个随机性提供者,我有时会出于测试目的而这样做,只需将 rand 替换为
MySecureRandom rand = new MySecureRandom();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
109682 次 |
| 最近记录: |