AES随机密钥生成

时间:2018-02-13 12:09:03

标签: java encryption cryptography aes

我看到许多以这种方式生成密钥的示例:

KeyGenerator generator = KeyGenerator.getInstance("AES");
generator.init(KEY_LEN);
SecretKey secretKey = generator.generateKey();

我怀疑是否存在以下差异(甚至是概念上的):

byte[] material = new byte[KEY_LEN / Byte.SIZE];
SecureRandom.getInstanceStrong().nextBytes(material);
SecretKey secretKey = new SecretKeySpec(material, "AES");

说明这两种方法都是3行,是否有一些实际影响,而不是第一种方法?

由于

3 个答案:

答案 0 :(得分:5)

您可以查看generateKey()的实际源代码以查看差异,但最终他们将执行相同的步骤来生成AES密钥。我会争论后者

byte[] material = new byte[KEY_LEN / Byte.SIZE];
SecureRandom.getInstanceStrong().nextBytes(material);
SecretKey secretKey = new SecretKeySpec(material, "AES");

对于普通编码器来说更脆弱,要求他们理解SecureRandom类。如果你完全消除了第二行,那么代码就可以使用全零键运行,这是一个明显的漏洞,攻击者也很容易检查。此外,如果算法有一些特殊要求,使用generateKey()可以生成格式正确的密钥。例如,现在过时的DES和Triple DES算法在每个字节中都有一个奇怪的奇偶校验位,这是某些DES实现期望看到的。

答案 1 :(得分:2)

这两个代码示例似乎正在做同样的事情,并且通常已经回答了。

然而,默认情况下,使用安全设备(例如HSM,智能卡或其他加密设备),他们不会允许暴露关键字节,因此您只能在非常方便的字节数组中生成密钥。有限的案例..

答案 2 :(得分:2)

有很多原因可以解释为什么你需要使用{em>设计的KeyGenerator方法:

  • 可读性:generateKey准确告诉您算法正在做什么;
  • 便携性:例如选择不同的算法时);
  • 正确性:SecretKeySpec可能无法完全验证密钥;
  • 安全性:您可以将密钥材料暴露在material变量中,这可能不会被清除,甚至在不再需要密钥后进行垃圾回收;
  • 硬件支持:硬件设备通常不支持导入密钥材料;密钥应该在设备上生成(使用专门的KeyFactory实现)。

完全没有理由使用第二种方法。如果要使用非常特定的随机数生成器生成密钥,则可以使用one of the specialized init methods但请注意,这可能与硬件设备不兼容。