有效数据填充数据的 RSA 解密失败 (BadPaddingException)
在Java中使用RSA加密/解密时,我遇到了一个非常特殊的问题。
示例代码:
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
KeyPair kp = kpg.genKeyPair();
Cipher enc = Cipher.getInstance("RSA");
enc.init(Cipher.ENCRYPT_MODE, kp.getPublic());
String CipherText = new String(enc.doFinal(PlainText.getBytes()));
System.out.println("CipherText: ") + CipherText);
Cipher dec = Cipher.getInstance("RSA");
dec.init(Cipher.DECRYPT_MODE, kp.getPrivate());
PlainText = new String(dec.doFinal(CipherText.getBytes()));
System.out.println("PlainText: " + PlainText);
大家可以清楚地看到:我使用公钥对明文进行加密,然后使用私钥对密文进行解密。
此代码崩溃并显示以下消息:
Exception in thread "main" javax.crypto.BadPaddingException: Data must start with zero
我还尝试显式使用“RSA/ECB/NoPadding”,但在解码期间失败。 (例如,解码后的密文与原始明文不匹配)。
最后但并非最不重要的一点是,我尝试在使用我自己的 PKCS1.5 填充函数 ala PKCS1.5 规范时执行此操作:
EMB = 00 || 02 ||研发|| 00||医学博士
EMB 是长度为 k 的编码消息块
其中 RD 是 8 个随机非零字节
MD 的最大长度 k = 11,并且可以选择用零字节填充以使 EMB 长度为 k。
经过两天的测试,我只能得出结论,Java 中的 RSA 算法有缺陷,或者根本没有达到我预期的效果。
对上述代码的任何建议或修复都非常受欢迎,因为我完全不明白为什么上述代码不能简单地按预期工作。
I am facing a very peculiar problem when using RSA encryption/decryption in Java.
Example code:
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
KeyPair kp = kpg.genKeyPair();
Cipher enc = Cipher.getInstance("RSA");
enc.init(Cipher.ENCRYPT_MODE, kp.getPublic());
String CipherText = new String(enc.doFinal(PlainText.getBytes()));
System.out.println("CipherText: ") + CipherText);
Cipher dec = Cipher.getInstance("RSA");
dec.init(Cipher.DECRYPT_MODE, kp.getPrivate());
PlainText = new String(dec.doFinal(CipherText.getBytes()));
System.out.println("PlainText: " + PlainText);
As everyone can plainly see: I encrypt the plaintext using the public key, after which I decrypt the ciphertext using the private key.
This code crashes with the following message:
Exception in thread "main" javax.crypto.BadPaddingException: Data must start with zero
I also tried to explicitly use "RSA/ECB/NoPadding", and this fails on decoding period. (Eg the decoded ciphertext doesn't match the original plaintext).
Last but not least, I have tried to perform this when using my own PKCS1.5 padding function ala the PKCS1.5 specs:
EMB = 00 || 02 || RD || 00 || MD
EMB is encoded messageblock of length k
Where RD are 8 random nonzero bytes
MD is max length k = 11, and optionally padded with zero bytes to make EMB length k.
After two days of testing I can only conclude that the RSA algo in Java is flawed or simply not performing what I expect it to perform.
Any suggestions or fixes to the above code are very welcome, as I am completely stumped on why the above code will not simply work as expected.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不要这样做:
有两个原因:
String.getBytes()
几乎永远不是一个好主意。您真的希望结果取决于系统默认编码吗?您可以使用 Apache Commons Codec 执行 base64 编码/解码操作,或 这个独立的公共域编码器/解码器。
Don't do this:
Two reasons:
String.getBytes()
without specifying an encoding. Do you really want the result to depend on the system default encoding?You can use Apache Commons Codec to perform the base64 encode/decode operations, or this standalone public domain encoder/decoder.