![](/img/trans.png)
[英]Exception in thread “main” javax.crypto.BadPaddingException: Decryption error
[英]Exception in thread “main” javax.crypto.BadPaddingException: Decryption error in Java
我们致力于用 Java 进行 RSA 加密/解密。
我们能够执行加密但解密出错
下面是我们正在使用的代码片段
public class RSA_Read_Write_Key {
static String plainText = "This RSA Crypto Java Code";
public static void main(String[] args) throws Exception {
byte[] cipherTextArray = encrypt(plainText, "D:\\TCE\\public.key");
String encryptedText = Base64.getEncoder().encodeToString(cipherTextArray);
System.out.println("Encrypted Text : " + encryptedText);
String decryptedText = decrypt(cipherTextArray, "D:\\TCE\\private.key");
System.out.println("DeCrypted Text : " + decryptedText);
}
public static Key readKeyFromFile(String keyFileName) throws IOException {
Key key = null;
InputStream inputStream = new FileInputStream(keyFileName);
ObjectInputStream objectInputStream = new ObjectInputStream(new BufferedInputStream(inputStream));
try {
BigInteger modulus = (BigInteger) objectInputStream.readObject();
BigInteger exponent = (BigInteger) objectInputStream.readObject();
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
if (keyFileName.startsWith("public"))
key = keyFactory.generatePublic(new RSAPublicKeySpec(modulus, exponent));
else
key = keyFactory.generatePrivate(new RSAPrivateKeySpec(modulus, exponent));
}
catch (Exception e) {
e.printStackTrace();
} finally {
objectInputStream.close();
}
return key;
}
public static byte[] encrypt(String plainText, String fileName) throws Exception {
Key publicKey = readKeyFromFile("D:\\TCE\\public.key");
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] cipherText = cipher.doFinal(plainText.getBytes());
return cipherText;
}
public static String decrypt(byte[] cipherTextArray, String fileName) throws Exception {
Key privateKey = readKeyFromFile("D:\\TCE\\private.key");
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte [] plain = new byte[100];
byte[] decryptedTextArray = cipher.doFinal(cipherTextArray);
return new String(decryptedTextArray);
}
}
当我们运行代码时,我们会遇到错误。 有人可以帮助解决这个问题吗?
Exception in thread "main" javax.crypto.BadPaddingException: Decryption error
at sun.security.rsa.RSAPadding.unpadV15(Unknown Source)
at sun.security.rsa.RSAPadding.unpad(Unknown Source)
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:2164)
at RSAcrypto.RsaToy.decrypt(RsaToy.java:108)
at RSAcrypto.RsaToy.main(RsaToy.java:34)
我发现了以下问题:
在readKeyFromFile()
,检查传递的文件路径是否以public
开头。 如果是,则生成公钥。 这仅在路径仅包含文件名时才有效,通常情况并非如此,例如在当前代码中使用路径D:\\\\TCE\\\\public.key
。 为了解决这个问题,最好应用new File(keyFileName).getName().startsWith("public")
而不是keyFileName.startsWith("public")
。
在encrypt()
和decrypt()
传递的文件路径fileName
应该转发到readKeyFromFile()
。 相反,硬编码路径D:\\\\TCE\\\\public.key
被传递。 这可能已更改仅用于测试目的。
通过这些更改,只要以适当的格式使用密钥,代码就可以在我的机器上运行。 这不是像 PKCS#8、PKCS#1 或 X.508 这样的典型格式之一,而是(如BigInteger
)序列化的模数和指数(公共或私有取决于密钥类型),因此两者都可以用ObjectInputStream
读取. 以这种格式存储密钥的一种方法是使用ObjectOutputStream
序列化模数和指数(如BigInteger
)。
另请注意,在某些地方编码(例如plainText.getBytes()
)和解码(例如new String(decryptedTextArray)
plainText.getBytes()
new String(decryptedTextArray)
)是在没有指定字符集的情况下完成的,因此使用(依赖于环境的)默认字符集(这可能导致如果加密和解密在不同的环境中执行会出现问题)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.