有效数据填充数据的 RSA 解密失败 (BadPaddingException)

发布于 2024-11-10 01:47:55 字数 1152 浏览 2 评论 0原文

在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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ゃ懵逼小萝莉 2024-11-17 01:47:55

不要这样做:

String CipherText = new String(enc.doFinal(PlainText.getBytes()));

有两个原因:

  • 在不指定编码的情况下调用 String.getBytes() 几乎永远不是一个好主意。您真的希望结果取决于系统默认编码吗?
  • 将二进制加密操作的结果(即不透明的二进制数据)视为编码字符串绝对不是一个好主意。改为使用 Base64 或十六进制对其进行编码。

您可以使用 Apache Commons Codec 执行 base64 编码/解码操作,或 这个独立的公共域编码器/解码器

Don't do this:

String CipherText = new String(enc.doFinal(PlainText.getBytes()));

Two reasons:

  • It's almost never a good idea to call String.getBytes() without specifying an encoding. Do you really want the result to depend on the system default encoding?
  • It's definitely never a good idea to treat the result of a binary encryption operation (i.e. opaque binary data) as an encoded string. Encode it in Base64 or hex instead.

You can use Apache Commons Codec to perform the base64 encode/decode operations, or this standalone public domain encoder/decoder.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文