英文:
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 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[] 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)
英文:
We working on RSA encryption/Decryption in Java.
We are able to perform encryption but getting error for decryption
Below is code snippet we are using
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);
}
}
When we run the code we getting below Error. Can someone help to resolve this?
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)
答案1
得分: 3
我发现了以下问题:
-
在
readKeyFromFile()
函数中,检查传递的文件路径是否以public
开头。如果是,则生成公钥。但这只在路径只包含文件名的情况下有效,而通常并非如此。例如,在当前代码中使用了路径D:\\TCE\\public.key
。为了解决这个问题,最好使用new File(keyFileName).getName().startsWith("public")
替代keyFileName.startsWith("public")
。 -
在
encrypt()
和decrypt()
中传递给readKeyFromFile()
的文件路径fileName
应该被转发。然而实际上传递的是硬编码的路径D:\\TCE\\public.key
。这可能仅为了测试目的而更改。
通过这些改变,只要密钥以适当的格式使用,代码在我的机器上能够工作。这种格式不是像 PKCS#8、PKCS#1 或 X.508 这些典型格式之一,而是(作为 BigInteger
)序列化的模数和指数(根据密钥类型是公钥还是私钥),因此两者都可以用 ObjectInputStream
进行读取。以这种格式存储密钥的一种方法是使用 ObjectOutputStream
序列化模数和指数(作为 BigInteger
)。
还请注意,在某些地方进行编码(例如 plainText.getBytes()
)和解码(例如 new String(decryptedTextArray)
)时,没有指定字符集,因此会使用(与环境相关的)默认字符集(如果在不同的环境中执行加密和解密,则可能会导致问题)。
英文:
I' ve found the following problems:
-
In
readKeyFromFile()
it is checked whether the passed file path starts withpublic
. If so, the public key is generated. This only works if the path consists only of the file name, which is generally not the case, e.g. in the current code the pathD:\\TCE\\public.key
is used. To solve this problem it would be better to applynew File(keyFileName).getName().startsWith("public")
instead ofkeyFileName.startsWith("public")
. -
The file path
fileName
passed inencrypt()
anddecrypt()
should be forwarded toreadKeyFromFile()
. Instead the hard coded pathD:\\TCE\\public.key
is passed. This may have been changed for test purposes only.
With these changes, the code works on my machine as long as keys are used in an appropriate format. This is not one of the typical formats like PKCS#8, PKCS#1 or X.508, but the (as BigInteger
) serialized modulus and exponent (public or private depending on the key type), so that both can be read with ObjectInputStream
. One way to store a key in this format is to serialize the modulus and exponent (as BigInteger
) with ObjectOutputStream
.
Please also note that in some places encoding (e.g. plainText.getBytes()
) and decoding (e.g. new String(decryptedTextArray)
) is done without specifying a character set, so that the (environment dependent) default character set is used (which can cause problems if encryption and decryption are performed in different environments).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论