当前位置: 首页 > 面试题库 >

如何在Java中创建安全的随机AES密钥?

暨曾笑
2023-03-14
问题内容

使用标准JDK在Java中生成安全的随机AES密钥的推荐方法是什么?

在其他帖子中,我发现了这一点,但是使用a SecretKeyFactory可能是一个更好的主意:

KeyGenerator keyGen = KeyGenerator.getInstance("AES");
SecureRandom random = new SecureRandom(); // cryptograph. secure random 
keyGen.init(random); 
SecretKey secretKey = keyGen.generateKey();

如果答案中包含对为什么这是生成随机密钥的一种好方法的解释,那将是很好的。谢谢!


问题答案:

我将使用您建议的代码,但略作简化:

KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256); // for example
SecretKey secretKey = keyGen.generateKey();

让提供者选择计划如何获得随机性-不要定义可能不如提供者已经选择的东西更好的东西。

该代码示例假定(如Maarten所指出的那样您已配置java.security文件以将首选提供程序包括在列表顶部。如果要手动指定提供程序,只需致电KeyGenerator.getInstance("AES","providerName");

使用KeyGenerator将是首选方法。正如Duncan指出的,我肯定会在初始化期间给出密钥大小。KeyFactory是一种应用于预先存在的密钥的方法。

好的,让我们深入了解这一点。原则上,AES密钥可以具有任何值。没有(3)DES中的“弱密钥”。也没有像(3)DES奇偶校验位中那样具有特定含义的位。因此,生成密钥就像生成带有随机值的字节数组并SecretKeySpec在其周围创建一个数组一样简单。

但是您使用的方法仍然有一些优势:KeyGenerator专门创建用于生成密钥。这意味着可以针对这一代优化代码。这可能会带来效率和安全性好处。例如,可以对它进行编程以避免出现可能暴露密钥的定时侧通道攻击。请注意,清除所有byte[]包含关键信息的内容可能已经是一个好主意,因为它们可能会泄漏到交换文件中(尽管如此,情况仍然如此)。

此外,如上所述,并非所有算法都使用完全随机密钥。因此使用KeyGenerator可以更轻松地切换到其他算法。不过,更现代的密码只能接受完全随机的密钥。与例如DES相比,这被视为一个主要的好处。

最后,就我而言,这是最重要的原因,该KeyGenerator方法是处理安全令牌(智能卡,TPM,USB令牌或HSM)中的AES密钥的唯一有效方法。如果您使用来创建byte[]SecretKeySpec则密钥必须来自内存。这意味着可以将密钥放入安全令牌中,但是无论如何密钥都将公开在内存中。通常,安全令牌仅与在安全令牌中生成的密钥或通过例如智能卡或密钥仪式注入的密钥一起使用。KeyGenerator可以与提供程序一起提供A ,以便在安全令牌内直接生成密钥。

如Duncan的答案所示:始终明确指定密钥大小(和其他任何参数)。不要依赖于供应商违约,因为这将使它不清楚你的应用程序在做,每个供应商都可能有自己的缺省值。

要获得真正的安全密钥,您需要使用硬件安全模块(HSM)来生成和保护密钥。HSM制造商通常会提供JCE提供程序,该提供程序将使用上面的代码为您完成所有密钥生成。



 类似资料:
  • 问题内容: 我正在用python创建一个项目,我想创建一个加密安全的随机数,我该怎么做?我已经在线阅读了常规随机生成器生成的数字不是密码安全的信息,并且该函数返回的是我的字符串,而不是数字。 问题答案: 您可以通过将函数应用于所返回的字节来获取随机数列表,如下所示 报价文件, 返回 适合加密使用* 的随机字节字符串。 * 该函数从特定于操作系统的随机性源返回随机字节。尽管返回的数据的确切质量取决于

  • 原始关闭原因未解决 我正在尝试编写一个程序,询问用户他想要生成多少安全代码,然后它会在一个数组中输出他所请求的代码。 安全代码长度应为7个字符,格式如下:NNNNLLL,其中N是随机数,L是随机大写字母。 该方法应通过随机选择字符,即数字和字母,以上述格式创建安全代码。 如果用户选择生成4个代码,我希望程序会输出这样的内容: "2394QAB""2821TSZ""7173AAY""2236WQA"

  • 问题内容: 这个问题:如何生成随机BigInteger描述了一种与BigIntegers实现与Random.nextInt(int n)相同的语义的方法。 我想对BigDecimal和Random.nextDouble()做同样的事情。 上述问题的一个答案建议创建一个随机的BigInteger,然后从中以随机的比例创建一个BigDouble。一个非常快速的实验表明这是一个非常糟糕的主意:) 我的直

  • 问题内容: PHP的函数不能提供良好的随机数。因此,我开始使用据说效果更好的产品。但是这些结果有多好?有什么方法可以再次改善它们? 我的点子: 这应该给您“完美的”随机数,不是吗? 问题答案: 伪随机数生成器(PRNG)是非常复杂的野兽。 没有真正的“完美”随机数生成器-实际上,可以通过数学函数完成的最好的操作是伪随机数-对于大多数意图和目的,它们似乎足够随机。 实际上,从PRNG返回的数字中执行

  • 问题内容: 我有一个Java属性对象,其中包含Web服务的身份验证信息。我需要对这些数据进行加密,但是我不知道该将加密密钥存储在何处才能保持安全。 关于加密和以安全方式检索数据的最佳实践是什么? 使用密钥库有什么好处吗? 问题答案: 您的问题很普遍。在Linux中,用户密码存储在纯文本文件中。尽管只存储了密码哈希,但是如果攻击者可以访问该文件,则使用脱机词典攻击可以很快发现一些密码。在这种情况下,