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

时间:2011-05-27 09:11:47

标签: java rsa encryption-asymmetric public-key-encryption

在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填充功能时尝试执行此操作,以及PKCS1.5规范:

EMB = 00 || 02 || RD || 00 || MD
EMB是编码长度为k的消息块 其中RD是8个随机非零字节
MD是最大长度k = 11,并且可选地用零字节填充以使EMB长度为k。

经过两天的测试后,我只能得出结论,Java中的RSA算法存在缺陷,或者根本无法执行我期望它执行的操作。

对上述代码的任何建议或修改都非常受欢迎,因为我完全难以理解上述代码为何不能按预期工作。

1 个答案:

答案 0 :(得分:2)

不要这样做:

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

有两个原因:

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

您可以使用Apache Commons Codec执行base64编码/解码操作,或this standalone public domain encoder/decoder