【问题标题】:java.security.NoSuchAlgorithmException:Cannot find any provider supporting AES/ECB/PKCS7PADDINGjava.security.NoSuchAlgorithmException:找不到任何支持 AES/ECB/PKCS7PADDING 的提供程序
【发布时间】:2023-03-13 14:38:02
【问题描述】:

我试图使用 AES 算法加密数据。 但是,发生了以下异常。

java.security.NoSuchAlgorithmException:
    Cannot find any provider supporting AES/ECB/PKCS7PADDING

有人知道这个问题的解决方案吗? 我的JDK版本是1.7。

【问题讨论】:

  • 请注意,ECB 不是 CPA 安全的,请改用 CBC(如果您只想存储数据的机密性)。

标签: java security encryption aes jce


【解决方案1】:

您不想为分组密码使用指定 PKCS#7 填充。您要指定 PKCS#5 填充。 PKCS#5 被指定用于分组密码,而 PKCS#7 不是(它用于不同的地方,如在 S/MIME 中)。我会指出 PKCS#5 和 PKCS#7 实际上指定了完全相同的填充类型(它们是相同的!),但在这种情况下使用时它被称为 #5。 :)

因此,您需要"AES/ECB/PKCS5PADDING",而不是"AES/ECB/PKCS7PADDING"。这是一个密码实现,Java 平台的每个实现都需要支持。有关详细信息,请参阅documentation of the Cipher class。

【讨论】:

  • 正确。它没有(好吧,因为#5和#7是相同的填充......我想你可以说它有?)。而且,不客气。如果您对它感到满意,请记住接受答案。 :)
  • 这个答案还可以,但有点令人困惑,因为您确实想使用 PKCS #7 填充作为分组密码。只是PKCS7Padding 是错误的名称,根据Standard Algorithm Names. PKCS #7 使用此填充方案来填充使用分组密码加密的消息。更大的上下文是什么并不重要。
  • 更令人困惑的是,.NET 调用完全相同的填充算法PKCS7 padding。
  • 虽然 Java 认为 PKCS5 和 PKCS7 填充是“相同的”(并且应该始终使用字符串“AES/CBC/PKCS5Padding”,因为“AES/CBC/PKCS7Padding”会导致抛出 NoSuchAlgorithmException使用 Java 加密 API 初始化 AES 分组密码时),我认为这在 Java 平台中是一个严重的错误命名,因为这些填充的纯技术定义并不相同。 PKCS5 明确将其块大小定义为严格的 8 字节,而 PKCS7 定义为从 1 到 255 的块大小(8 字节的块大小与 PKCS5 相同)。
  • 答案是正确的,但解释绝对不是。如果规范有任何指示,则 PKCS#5 填充应仅用于基于密码的加密,因为这是 PKCS#5 指定的。禁止 PKCS#7 填充作为分组密码的一般填充,因为 PKCS#7 主要指定加密消息语法因此是双层的。只有最后一句话有意义(但这是大部分答案,幸运的是)
【解决方案2】:

如果你想使用 AES/ECB/PKCS7Padding 那么充气城堡将支持 http://www.bouncycastle.org/specifications.html

【讨论】:

  • 是的,但它与下面的填充算法相同。
【解决方案3】:

有关包含 PKCS#5 和 PKCS#7 加密标准文本的问题的非常全面的解释,请查看here。


PKCS#5 填充表示填充 1 到 8 个字节。填充字节本身包含编码为字节的填充字节的数量。为 DES 指定了 PKCS#5 填充,但它适用于任何块大小为 8 字节的块密码。

现在,基于密码的加密的 DES 规范甚至 PKCS#5 规范比 Java 早了很长时间。 AES 仅在 2002 年标准化,在 Java 甚至 Java 2 被引入很久之后。因此,在 AES 出现之前,(三重)DES 和 PKCS#5 填充已集成到 Java 中。

当 Java - 或者更准确地说,Sun JCE 提供程序 - 获得 AES 功能时,它需要一个用于 16 字节块大小的填充方法。 PKCS#7 指定了is identical to PKCS#5 padding 的这种填充方法,除了它是为 2 到 255 字节的块大小定义的(如果它编码基于零的无符号整数,则为字节的最大值)。但是,填充方法已经存在;它被命名为"PKCS5Padding"。因此,"PKCS5Padding" 没有引入新名称,而是简单地重复使用。

到目前为止,Sun 提供商应该真正支持"PKCS7Padding",因为 PKCS#5 填充根本不正确。这不仅仅是 Java 命名问题,对于任何尝试实现加密协议或将其他应用程序移植到 Java 的开发人员来说都是一个问题。但是现在,您应该使用"PKCS5Padding" 而不是"PKCS7Padding"。

【讨论】:

    【解决方案4】:

    解决方案: Step1:将 bcprov-ext-jdk16-1.46.jar (https://mvnrepository.com/artifact/org.bouncycastle/bcprov-ext-jdk16/1.46) 添加到您的项目中

    Step2:添加行“Security.addProvider(new BouncyCastleProvider());”开始使用 init Cipher common

    然后,运行项目,OK,解密成功。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多