2011-05-27 86 views
2

在Java中使用RSA加密/解密时,我遇到了一个非常奇怪的问题。有效数据填充数据的RSA解密失败(BadPaddingException)

示例代码:

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
的messageblock其中RD是8个随机非零字节
MD是最大长度为k = 11,并且任选地与零个字节填充到使EMB长度为k。

经过两天的测试,我只能断定Java中的RSA算法存在缺陷或者根本没有执行我期望的性能。

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

回答

2

不要这样做:

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

两个原因:

  • 这几乎从未一个好主意,打电话String.getBytes()没有指定的编码。你真的希望结果取决于系统默认编码吗?
  • 将二进制加密操作的结果(即不透明二进制数据)作为编码字符串处理绝对不是一个好主意。使用Base64或十六进制进行编码。

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

+0

非常感谢Jon。经过另一次测试,我忽略了字符串转换,之后它正常运行。它还早*叹气* – djBo 2011-05-27 09:22:57