【问题标题】:Cannot find any provider supporting RSA/None/OAEPWITHSHA-256ANDMGF1PADDING找不到任何支持 RSA/None/OAEPWITHSHA-256ANDMGF1PADDING 的提供程序
【发布时间】:2021-03-09 18:01:42
【问题描述】:

我在 javax crypto 中使用 RSA 加密时遇到了一个奇怪的问题。我使用RSA/None/OAEPWITHSHA-256ANDMGF1PADDING模式如下:

 Cipher cipher = Cipher.getInstance("RSA/None/OAEPWITHSHA-256ANDMGF1PADDING");

它在我的 Spring Boot 项目中正常工作。但是当我在同一个项目中通过main(String[] args) 调用相同的函数时,我遇到了问题 Cannot find any provider supporting RSA/None/OAEPWITHSHA-256ANDMGF1PADDING。同样,如果我使用RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING,我会得到正确的输出(我不想使用 ECB,因为我知道它在 RSA 算法中没有用处)。

另外,在我的另一个 Spring Boot 项目中,我遇到了同样的上述问题(这次不仅是 main(String[] args),而且在 Spring Boot 项目本身中也是如此)。

有人可以帮我解决这个问题吗?

【问题讨论】:

  • 我真的不确定所提供的密切原因是什么,它们对我来说根本没有任何意义。完全可以回答。

标签: java spring spring-boot cryptography sha


【解决方案1】:

基本上,"RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING" 中的 ECB 由 "SunJCE" 提供程序提供,是用词不当。它可能是从旧 Java 版本中的分组密码模式复制而来的。它确实不允许加密多个块,这正是您对 ECB 模式所期望的。换句话说,它与"RSA/None/OAEPWITHSHA-256ANDMGF1PADDING" 完全相同——但Java SE 通常不提供该算法。

它在您的 Spring Boot 项目中没有失败的原因是它可能包含 Bouncy Castle 提供程序(或提供此算法的其他提供程序)。然而,这是一个纯软件提供商,存在侧通道保护问题。通常,您应该更喜欢在 "SunJCE" 提供程序中的实现。

只使用"RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING" 而不明确指定提供者是最好的方法。


[编辑] 我强烈建议使用OAEPParameterSpec 和MGF1ParameterSpec 明确设置用于标签和MGF1 的SHA-256 哈希。不幸的是,Java 可能默认使用 SHA-1,并且始终使用相同的哈希函数是最兼容的选项。

【讨论】:

  • 感谢您的回答。是的,当我通过我的第一个 Spring Boot 项目打印提供程序时,它显示 BC。但是当我从 main 或另一个 Spring 项目打印时,它不会出现。我没有看到在第一个 Spring 引导项目中添加了 BC 提供程序。此外,我对这两个项目都使用相同的 JDK 11。所以,这对我来说是一个奇怪的行为。另外,我在使用SunJCE 提供程序时处于两难境地,因为它没有RSA/None/OAEPWITHSHA-256ANDMGF1PADDING 模式。那么你是否建议从SunJCE 使用RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING 而不是切换到Bouncy Castle?
  • 是的,这正是我的建议。
  • 我尝试使用RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING 模式使用公钥加密数据,并尝试使用RSA/None/OAEPWITHSHA-256ANDMGF1PADDING 使用相应的私钥解密。但我得到了错误:org.bouncycastle.jcajce.provider.util.BadBlockException: unable to decrypt block。如果它们相同,它不应该工作吗?对不起我的无知,因为我对密码学很陌生。 P.S.:如果我使用相同的密钥对和数据在加密和解密中使用相同的模式,我会得到正确的解密。
  • 这很奇怪。我唯一能想到的是标签和 MGF1 函数使用了不同的哈希值。尝试使用 OAEPParameterSpec 和 MGF1ParameterSpec 明确设置两者
  • 人们觉得这个 Q/A 很有用,你能看看最后的两个 cmets 吗?
【解决方案2】:

当我遇到这个问题时,我可以通过指定提供者 likeso 来解决它 Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider())。所以看来我们需要使用重载的构造函数

Cipher cipher = Cipher.getInstance("RSA/None/OAEPWITHSHA-256ANDMGF1PADDING", provider);

【讨论】:

  • 正如 Maarten Bodewes 回答 (stackoverflow.com/a/63442519/8166854) 中已经评论的那样,您可以在没有任何第三方库(如 Bouncy Castle)的情况下运行该算法。
猜你喜欢
  • 2015-07-07
  • 2015-11-16
  • 2020-03-17
  • 1970-01-01
  • 2021-11-16
  • 2019-05-27
  • 2015-08-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多