javax.crypto.BadPaddingException:解密错误
我已经成功地使用私钥和公钥进行了加密和解密,但是当我尝试使用RSAPrivateCrtKey而不是RSAPrivateKey应用RSA解密时,我遇到了这个错误 错误是:javax.crypto.BadPaddingException:解密错误,java,encryption,cryptography,Java,Encryption,Cryptography,我已经成功地使用私钥和公钥进行了加密和解密,但是当我尝试使用RSAPrivateCrtKey而不是RSAPrivateKey应用RSA解密时,我遇到了这个错误 错误是: javax.crypto.BadPaddingException: Decryption error ----------------DECRYPTION COMPLETED------------ at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:380)
javax.crypto.BadPaddingException: Decryption error
----------------DECRYPTION COMPLETED------------
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:380)
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:291)
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:363)
at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)
at javax.crypto.Cipher.doFinal(Cipher.java:2165)
at lab6.RSACRT.rsaDecrypt(RSACRT.java:132)
at lab6.RSACRT.main(RSACRT.java:63)
代码如下所述。提前谢谢
private byte[] rsaDecrypt(RSAPrivateCrtKey rsaprivateCrtKey, byte[] ciphertext) throws IOException {
System.out.println("\n----------------DECRYPTION STARTED------------");
byte[] descryptedData = null;
int cipher1= ciphertext.length;
System.out.println(cipher1);
try {
RSAPrivateCrtKey privateKey = readPrivateKeyFromFile(PRIVATE_KEY_FILE);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
descryptedData = cipher.doFinal(ciphertext);
System.out.println("Decrypted Data: " + new String(descryptedData));
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("----------------DECRYPTION COMPLETED------------");
return descryptedData;
}
public RSAPrivateCrtKey readPrivateKeyFromFile(String fileName) throws IOException{
FileInputStream fis = null;
ObjectInputStream ois = null;
try {
fis = new FileInputStream(new File(fileName));
ois = new ObjectInputStream(fis);
BigInteger modulus = (BigInteger) ois.readObject();
BigInteger exponent = (BigInteger) ois.readObject();
//Get Private Key
RSAPrivateCrtKeySpec rsaPrivateCrtKeySpec = new RSAPrivateCrtKeySpec(modulus, exponent, exponent, exponent, exponent, exponent, exponent, exponent);
KeyFactory fact = KeyFactory.getInstance("RSA");
RSAPrivateKey privateKey = (RSAPrivateKey) fact.generatePrivate(rsaPrivateCrtKeySpec);
return (RSAPrivateCrtKey) privateKey;
} catch (Exception e) {
e.printStackTrace();
}
finally{
if(ois != null){
ois.close();
if(fis != null){
fis.close();
}
}
}
return null;
}
}
正如Artjom已经提到的,您对
rsaprovatecrtkeyspec
的构造函数的调用是错误的。您似乎只需要一个正常的RSAPrivateKeySpec
,而不需要根据中国剩余定理(CRT)执行计算所需的参数
您现在拥有的是:
//Get Private Key
RSAPrivateCrtKeySpec rsaPrivateCrtKeySpec = new RSAPrivateCrtKeySpec(modulus, exponent, exponent, exponent, exponent, exponent, exponent, exponent);
KeyFactory fact = KeyFactory.getInstance("RSA");
RSAPrivateKey privateKey = (RSAPrivateKey) fact.generatePrivate(rsaPrivateCrtKeySpec);
return (RSAPrivateCrtKey) privateKey;
而您需要的是:
//Get Private Key
RSAPrivateKeySpec rsaPrivateKeySpec = new RSAPrivateKeySpec(modulus, exponent);
KeyFactory fact = KeyFactory.getInstance("RSA");
RSAPrivateKey privateKey = (RSAPrivateKey) fact.generatePrivate(rsaPrivateKeySpec);
return (RSAPrivateKey) privateKey;
当然,您还需要将方法的返回类型更改为RSAPrivateKey
或者,如果有更多的对象表示CRT参数,您可能需要更多的变量和对
(BigInteger)ois.readObject()的更多调用
RSA CRT大约比普通RSA快4倍(并且具有不同的定时攻击特征,但我认为这是一个更高级的主题)。新的RSAPrivateCrtKeySpec(模数、指数、指数、指数、指数、指数、指数)代码>-是您的问题。请阅读有关此处应传递的内容的文档,然后执行此操作。您可能还希望查看try with resources以更轻松地处理流,以及RSA with OAEP padding以使解密更安全。