当前位置: 首页 > 知识库问答 >
问题:

充气城堡vsJava默认RSA与OAEP

萧成文
2023-03-14

有人能解释一下为什么这段代码在解密密钥时会在最后一行抛出javax.crypto.BadPadding异常:解密错误吗?

// Given an RSA key pair...
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
KeyPair keyPair = keyGen.genKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();

// ... and an AES key:
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(256);
SecretKey aesKey = keyGenerator.generateKey();

// When I encrypt the key with this Bouncy Castle cipher:
Cipher encryptionCipher = Cipher.getInstance("RSA/NONE/OAEPWithSHA256AndMGF1Padding", "BC");
encryptionCipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedKey = encryptionCipher.doFinal(aesKey.getEncoded());

// Then trying to decrypt the key with this cipher...
Cipher decryptionCipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING");
decryptionCipher.init(Cipher.DECRYPT_MODE, privateKey);
// ... throws `javax.crypto.BadPaddingException: Decryption error` here:
decryptionCipher.doFinal(encryptedKey);

以下是来自https://stackoverflow.com/a/27886397/66722对于使用OAEP的RSA也是如此?

“RSA/ECB/PKCS1Padding”实际上没有实现ECB模式加密。它应该被称为“RSA/None/PKCS1Padding”,因为它只能用于加密单个明文块(或者实际上是一个密钥)。这只是Sun/Oracle的一个命名错误。

如果是这样,我希望这些转换是等价的,我上面的测试也会通过。两者中指定了相同的填充,那么为什么要使用BadPaddingExctive

不管怎样,我都希望外行能解释一下两者的区别。

共有1个答案

贾建茗
2023-03-14

有关更多信息的类似问题,请参阅Maarten Bodewes对此的回答。

转换字符串的“模式”部分无效。问题在于不同的提供者使用不同的默认值。这是不幸的,而且肯定是次优的。我们应该责怪太阳/甲骨文吗?除了对结果不满之外,我没有别的意见。

OAEP是一个相当复杂的结构,有两个不同的哈希函数作为参数。密码转换字符串允许您指定其中一个,您已经指定为SHA-256。然而,MGF1函数也由哈希函数参数化,您不能在密码转换字符串中指定。Oracle提供程序默认为SHA1,而BouncyCastle提供程序默认为SHA-256。因此,实际上,有一个隐藏的参数对互操作性至关重要。

解决方案是通过向密码提供OAEPParameterSpec来更全面地指定这些隐藏参数。init(…) 方法,如下例所示:

Cipher encryptionCipher = Cipher.getInstance("RSA/NONE/OAEPWithSHA256AndMGF1Padding", "BC");
OAEPParameterSpec oaepParameterSpec = new OAEPParameterSpec("SHA-256", "MGF1",
                MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT);
encryptionCipher.init(Cipher.ENCRYPT_MODE, publicKey, oaepParameterSpec);
// ...
// ...
// ...
Cipher decryptionCipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING");
oaepParameterSpec = new OAEPParameterSpec("SHA-256", "MGF1",
                MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT);
decryptionCipher.init(Cipher.DECRYPT_MODE, privateKey, oaepParameterSpec);

第一个选项实际上是不可操作的,因为这些已经是Bouncycastle的默认设置。

 类似资料:
  • 我的项目正在对来自某些第三方软件的某些数据集进行签名验证。使用的签名算法是 。当我使用SDK附带的标准SUN加密提供程序时,一切都很顺利。最近我切换到了Bouncy Castle 1.50,之后,一些以前(即SUN提供者)进行验证的数据集开始失败,而其余的仍然被验证正常。 我探索了两个提供程序的源代码,结果发现SDK的默认提供程序对格式错误的签名有某种保护(同时能够恢复),而Bouncy Cast

  • 我需要用Java中的Bouncy Castle创建一个自签名X509证书,但我尝试包含的每个类都不推荐使用。我该怎么解决这个问题?还有其他课程吗?谢谢

  • 我正在调试bouncy castle 1.47的一个问题。我可以找到“bcprov”的调试jar,但无法找到{org.bouncycastle:bcpkix-jdk15on:1.47:jar}的调试jar。 还有其他地方可以下载bcpkix-jdk15on-1.47吗。包含调试信息的jar? 或 是否有一种工具可以从没有行号的jar(包含. class文件)生成行号,并且还可以为相同生成的jar生

  • 我在玩加密。我被困在用BouncyCastle加载密钥上。密钥是由PuTTYgen(SSH-2 RSA 4096位)生成的。也许有其他方法可以加载它吗? 我得到: “System.IO”类型的未处理异常。BouncyCastle.Crypto中出现“IOException”。dll<br>其他信息:意外的内容结束标记“” 已添加:我使用“ssh-keygen -t rsa -b 4096”生成了一

  • 我有CMS加密数据使用弹跳城堡,我想解密它的内容。然而,我遇到了获取。我相信,秘密钥匙有问题

  • 我正在开发一个功能来对某些内容进行数字签名。我有一个带有私钥的有效证书。如何使用私钥和充气城堡进行数字签名? 我尝试了以下方法,但想要一些正确的方法来实现同样的使用充气城堡: 谢谢!