【问题标题】:Java default Crypto/AES behaviorJava 默认加密/AES 行为
【发布时间】:2011-09-09 15:00:48
【问题描述】:

有谁知道默认的 Java 加密行为是干什么用的:

SecretKeySpec localSecretKeySpec = new SecretKeySpec(arrayOfByte, "AES");
Cipher localCipher = Cipher.getInstance("AES");

具体来说,我希望了解这些类如何生成 IV,以及仅指定“AES”时的默认加密模式是什么。谢谢。

【问题讨论】:

  • 不要引用我的话,但这很容易取决于提供者。您确实希望始终指定操作模式和填充算法。不这样做会导致很多问题......
  • 你真的能接受这些答案之一吗?你最近的问题是不久前的,所以你应该还在。

标签: java cryptography aes


【解决方案1】:

这些细节是特定于提供商的,依赖默认模式和填充可能非常危险。如果您对当前与 Java 捆绑的默认提供程序使用的值感兴趣,您将不得不寻找相关算法的源代码。例如,它用于 RSA 算法的默认值是here。此外,Java™ Cryptography Architecture (JCA) Reference Guide 有相当多的信息可以回答你们中的一些其他问题。

【讨论】:

    【解决方案2】:

    对于 Oracle JDK 7(已测试),AES 的默认密码是 AES/ECB/PKCS5Padding。 Java 安全文档没有提到这一点(http://docs.oracle.com/javase/6/docs/technotes/guides/security/StandardNames.html#algspec),必须做一些 JUnit 测试才能找到.

    【讨论】:

    • 我可以确认,当仅请求 AES 时,1.6.0_31 也使用 AES/ECB/PKCS5Padding。通过加密约 10MB 的 /dev/urandom 各种组合进行测试。
    • 我已经搜索了好几个小时了!谢谢!
    • @Jesse - Cipher.getAlgorithm() 应该返回您正在使用的内容。请参阅 Java 的 Standard Algorithm Name Documentation
    • 非常感谢您。几个小时以来,我一直在寻找解决方案。如果你想在 C# 中解密用 Java 加密的东西,不要忘记将块大小设置为 128,因为 Java 遵循特定的 AES 标准。
    • @jww Cipher.getAlgorithm() 在这样请求时仍返回“AES”(OpenJDK 11)。变量com.sun.crypto.provider.CipherCore.cipherpadding 揭示了执行doFinal 时的实际设置。
    【解决方案3】:

    详细信息因提供商而异。 JCA Reference Guide 表示:

    (创建密码对象)如果未指定模式或填充,则使用模式和填充方案的特定于提供程序的默认值。例如,SunJCE 提供程序使用 ECB 作为默认模式,PKCS5Padding 作为 DES、DES-EDE 和 Blowfish 密码的默认填充方案。这意味着对于 SunJCE 提供程序:Cipher.getInstance("DES") 和 Cipher.getInstance("DES/ECB/PKCS5Padding") 是等效的语句。

    我将始终使用完整的形式(算法/模式/填充),不仅因为我认为在实现中省略此类“细节”是不好的做法,而且还因为实现了独立于所选提供者的密文(通常为存储/传输加密,然后无法确定稍后/另一端将使用相同的提供者)。

    【讨论】:

      【解决方案4】:

      这取决于提供者。不同的提供者可能有不同的默认参数。这是 Java 8 的链接。

      https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#ciphertrans

      javax.crypto.Cipher.getInstance(String transformation) 工厂 方法使用以下形式的转换生成密码 算法/模式/填充。如果省略模式/填充,则 SunJCE 和 SunPKCS11 提供者使用 ECB 作为默认模式和 PKCS5Padding 作为许多对称密码的默认填充。

      建议使用完全指定 算法、模式和填充,而不是依赖默认值。

      注意:ECB 适用于单个数据块,并且可以 并行化,但一般不应用于多个块 数据。

      因此,您不应只使用 AES,而应指定模式和填充。此外,虽然 getInstance 方法可以为提供者提供另一个参数,但不建议这样做,因为

      应用程序与可能不可用的特定提供程序绑定 关于其他 Java 实现

      【讨论】:

      • 这应该是公认的答案,因为它链接到文档中提到它的确切位置。不幸的是,我没有检查所有答案,所以我自己花了一段时间才找到那段。它在 Java 6 文档版本中不存在,但自 Java 7 以来就存在。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-05
      • 1970-01-01
      • 2012-03-28
      • 2012-06-01
      • 2017-05-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多