【问题标题】:Using "RSA/ECB/PKCS7Padding" with Bouncy Castle在 Bouncy Castle 中使用“RSA/ECB/PKCS7Padding”
【发布时间】:2015-03-22 00:39:57
【问题描述】:

我尝试使用“RSA/ECB/PKCS7Padding”进行加密。 JCE 不支持它。所以我下载了 Bouncy Castle 但似乎 Bouncy Castle 也不支持这种转换。以下代码:

Security.insertProviderAt(new BouncyCastleProvider(), 1);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS7Padding");

抛出

Caused by: java.security.NoSuchAlgorithmException: Cannot find any provider supporting RSA/ECB/PKCS7Padding
    at javax.crypto.Cipher.getInstance(Cipher.java:524)
    ....
Caused by: javax.crypto.NoSuchPaddingException: Unsupported padding PKCS7Padding
    at sun.security.pkcs11.P11RSACipher.engineSetPadding(P11RSACipher.java:129)
    at javax.crypto.Cipher$Transform.setModePadding(Cipher.java:360)
    at javax.crypto.Cipher.getInstance(Cipher.java:517)
    ... 4 more

我做得对吗?

TIA。

【问题讨论】:

  • Cipher.getInstance("RSA/ECB/PKCS1Padding");适用于 bcprov-jdk16-1.46.jar
  • 你可以使用规范bouncycastle.org/specifications.html中的算法
  • PKCS1 为 RSA 指定填充。 PKCS5/7 指定了块密码的填充,而 RSA 没有。
  • 给出的要求是应该使用 RSA 并指定“PKCS7 with Padding”。没有提及该模式(ECB等)。我可以将 NONE 设置为模式吗?
  • 我还想指出 PKCS#1v1.5 填充(通常称为 PKCS1 填充)已被破坏。应该使用 OAEP 填充(在 PKCS#1v2.0 中指定)。

标签: java encryption cryptography rsa bouncycastle


【解决方案1】:

总结我的评论,根据 java7 文档,JCE Cipher API 的每个实现都必须支持标准算法列表。充气城堡也支持其他算法。我在我的应用程序中使用“AES/ECB/PKCS7Padding”。您可以在 algorithm section"RSA/ECB/PKCS1Padding""RSA/NONE/PKCS1Padding" 中找到 bouncy castle 支持的算法。

【讨论】:

  • 我想使用“RSA/ECB/PKCS7Padding”,而不是“AES/ECB/PKCS7Padding”。我下载的充气城堡jar是bcprov-ext-jdk15on-151.jar。是否支持“RSA/ECB/PKCS7Padding”?
  • @user3573403:PKCS7 使用 RSA 填充实际上没有任何意义。
  • 嗨@GregS,为什么PKCS7 使用RSA 填充没有意义?这是给我的要求。
【解决方案2】:

不可能按照RFC2315 section 10.3 注释 2 中所述对所有 RSA 密钥大小实施 PKCS#7 填充:

一些内容加密算法假设 输入长度是 k 个八位字节的倍数,其中 k > 1,并且 让应用程序定义处理输入的方法 其长度不是 k 个八位字节的倍数。对于这样 算法,该方法应是在输入填充 以 k 结尾 - (l mod k) 八位字节都具有值 k - (l mod k),其中 l 是输入的长度。其他 的话,输入在尾端用以下之一填充 以下字符串

特别是:

当且仅当 k

这意味着您可以使用 2048 位密钥为 RSA 实现此功能,但对于任意数据来说,4096 位密钥已经太多了。这就是为什么 PKCS7Padding 保留用于块密码,其中每个块通常在 128 和 256 位之间。这也是图书馆一般不支持这种组合的原因。

上述规范包含实现 PKCS#7 填充方案所需了解的所有内容。当您这样做时,您将使用它填充您的数据,然后使用RSA/ECB/NoPadding 进行加密。您可能会遇到这样的问题,虽然填充的明文和密钥大小相同,但加密不起作用。那是因为您填充的明文可能仍会超过密钥。您可能需要在明文前面添加一个零字节,并且只填充(0x00 + 明文),以便取消设置最高有效位。

【讨论】:

  • 上面遗漏的事实是 PKCS#7 填充不会是加密安全的(除了您描述的大小的操作问题)。另请参阅我的答案,了解更可能需要 PKCS#7 的情况。
  • 对不起,我只是对加密有一个基本的了解,你们所说的只是我所不能理解的。我的要求基本上是这样的:我们有一个随机的一次性 AES-256 密钥,我们需要使用接收者的公钥(RSA-2048)加密这个 AES 密钥。对此 AES 密钥的加密要求是“RSA-2048, PKCS7 with padding in envelope mode”。我该怎么做?
  • @user3573403 这是一个奇怪的请求,正如您从答案中注意到的那样。我不完全确定为 RSA 实现 PKCS#7 是否是一个好主意,因为我的建议将其转换为普通 PKCS#7 填充以外的其他内容(因为前导零字节)。这个要求似乎是有人向你规定的。所以,我猜这是一个互操作性问题,在这种情况下你可以实现它并查看它是否有效。我不会提供代码来执行此操作,因为我认为这是一个坏主意(正如 Maarten 所说,它不是 CPA 安全的)。
  • @user3573403 这仍然有可能是一个误解,您的意思是 RSA/ECB/PKCS1Padding 与 AES/ECB/PKCS5Padding 以混合加密方式。
【解决方案3】:

即使存在这样的事情,使用带有 PKCS#7 填充的 RSA 或直接从 PKCS#7 填充派生的方案也是不安全的(或者更准确地说,它不是 CPA 安全的)。

更可能的是,客户端不需要 PKCS#7 padding,但加密数据应包含在 CMS message format 中。 PKCS#7 是此格式的前身,PKCS#7 填充只是此规范的一小部分。

Bouncy Castle 包含这种格式的实现:

S/MIME 和 CMS (PKCS7/RFC 3852) 的生成器/处理器。

当前包含在bcpkix* JAR 文件中。

【讨论】:

  • 对不起,我只是对加密有一个基本的了解,你们所说的只是我所不能理解的。我的要求基本上是这样的:我们有一个随机的一次性 AES-256 密钥,我们需要使用接收者的公钥(RSA-2048)加密这个 AES 密钥。对此 AES 密钥的加密要求是“RSA-2048, PKCS7 with padding in envelope mode”。我该怎么做?
  • 首先阅读我链接到的 CMS 规范。抱歉,这个空间对于 CMS 的完整解释来说有点短。包络模式当然是 CMS 规范的一部分,因此您不仅需要 PKCS#7 填充 - 正如我在答案中已经提到的那样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-25
  • 1970-01-01
  • 2011-07-12
  • 2012-07-05
  • 1970-01-01
  • 2018-01-13
  • 1970-01-01
相关资源
最近更新 更多