I encountered the abovementioned exception while I was decrypting a string.
Below is my code:
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
public class EncryptAndDecrypt {
public static Cipher createCipher () throws Exception{
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
return cipher;
}
public static KeyPair generateKey () throws NoSuchAlgorithmException{
KeyPairGenerator keyGen = KeyPairGenerator.getInstance ("RSA");
keyGen.initialize(1024);
KeyPair key = keyGen.generateKeyPair();
return key;
}
public static byte [] encrypt (String str, Cipher cip, KeyPair key) {
byte [] cipherText = null;
try {
byte [] plainText = str.getBytes("UTF8");
cip.init(Cipher.ENCRYPT_MODE, key.getPublic());
cipherText = cip.doFinal(plainText);
} catch (Exception e) {
e.printStackTrace();
}
return cipherText;
}
public static String decrypt (byte [] c, Cipher cip, KeyPair key) throws Exception {
cip.init(Cipher.DECRYPT_MODE, key.getPrivate());
byte [] decryptedPlainText = cip.doFinal (c);// exception occurred here
String decryptedPlainStr = new String (decryptedPlainText);
return decryptedPlainStr;
}
}
//separate class below to use the encrypt method
public class EncryptionApp {
public static void main (String [] args) {
getEncrypted();
}
public static byte [] getEncrypted () {
byte [] encyptedByte = null;
try {
String plainText = "der";
Cipher cip = Safety.createCipher();
KeyPair key = Safety.generateKey();
encyptedByte = Safety.useRSA(plainText, cip, key);
}
catch (Exception e) {
e.printStackTrace();
}
return encyptedByte;
}
}
// Another class to use the decrypt method
public class DecryptionApp {
public static void main(String[] args) {
System.out.println (useDecrypted () );
}
public static byte[] useDecrypted () {
byte [] decryptedText = null;
try {
Cipher cip = EncryptAndDecrypt.createCipher();
KeyPair key = EncryptAndDecrypt.generateKey();
decryptedText = EncryptAndDecrypt.decrypt(EncryptionApp.getEncrypted(),cip,key);
}
catch (Exception e) {
e.printStackTrace();
}
return decryptedText;
}
}
I was getting this error and it turned out in my case to be that the base 64 string I was sending as a parameter contained some characters that were being altered because of being in a URL. The solution turned out to be URL encoding the parameter.
Have you googled? A lot of people have this problem when the key to encrypt is not the same as the key to decrypt. It seems like you generate new keys all the time instead of using the same key to decrypt that you used for encryption.
You already asked the same question in "javax.crypto.BadPaddingException: Data must start with zero" exception, and I gave you an answer: you're using two different keypairs : one to encrypt, and another one to decrypt. That can't work. I even gave you a code sample showing that everything ran fine if you used the same keypair.
KeyPairGenerator.generateKeyPair() generates a keypair. Calling this method twice will get you two different keypairs: it uses a random number generator internally to generate always different keypairs.
You must generate a keypair once, store it in a variable, and use this variable to encrypt and decrypt.
You should read the documentation of the classes and methods you are using. The documentation of generateKeyPair says:
Add this main method to EncryptAndDecrypt, and execute it. You'll see that evrything works fine.
The problem lies in the way you're using this class. The
useDecrypted
method does the following:And the
getEncrypted
method does the following:So, in short, you use two different keypairs : one to encrypt and the other to decrypt. That can't work.
Also, note that in
encrypt
, you transform your string into a byte array using the UTF8 encoding, whereas indecrypt
, you transform the byte array into a String using the default platform encoding. You should use UTF8 for both, and thus use the following code in decrypt :