ARP ARP - 22 days ago 10
Android Question

BadPaddingException decrypting the encrypted data in Android

Hi I'm new to android security concepts,
Reading some blogs in get to know about we can encrypt data using Public key and can decrypt it using respective Private key, Encryption seems to be doesn't have any problem, but when I try to decrypt it, it throws

javax.crypto.BadPaddingException: error:0407106B:rsa routines:RSA_padding_check_PKCS1_type_2:block type is not 02.
Could please some one help me out in solving this problem, My code is as follows,

public String RSAEncrypt(final String plain, PublicKey publicKey ) throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, IllegalBlockSizeException, BadPaddingException {

Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte [] encryptedBytes = cipher.doFinal(plain.getBytes());
String encrypted = bytesToString(encryptedBytes);
System.out.println("EEncrypted?????" + encrypted );
return encrypted;
}

public String RSADecrypt(String encryptedBytes,PrivateKey privateKey ) throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchProviderException {
Cipher cipher1 = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher1.init(Cipher.DECRYPT_MODE, privateKey);
byte [] decryptedBytes = cipher1.doFinal(stringToBytes(encryptedBytes));

String decrypted = new String(decryptedBytes);
System.out.println("DDecrypted?????" + decrypted);
return decrypted;
}

public String bytesToString(byte[] b) {
byte[] b2 = new byte[b.length + 1];
b2[0] = 1;
System.arraycopy(b, 0, b2, 1, b.length);
return new BigInteger(b2).toString(36);
}

public byte[] stringToBytes(String s) {
byte[] b2 = new BigInteger(s, 36).toByteArray();
return Arrays.copyOfRange(b2, 1, b2.length);
}


Stack trace is as follows:

07-28 11:27:35.119: I/System.out(22933): KEYSTORE : String to encrypt = > Hello
07-28 11:27:35.119: I/System.out(22933): KEYSTORE : [B@41bbf4d0
07-28 11:27:38.422: I/System.out(22933): KEYSTORE : String to Decrypt = > UJGAchuDhu3mqH5YPjmYqKBapJYMjJRk9g6HIy8bANooWorzwqgiEo+dOse6Nfq7i0yzw/Wt7TSdTNiYROxehkZvEx/mW5+Niw1CgZ2y9b/ijTeNTF+7aGPrqfDXJ38hUFdTPc6oNl2FVOIafncGOSK9po1JOAYeK0JiA2KrACfPLPjsLQSRzseThyYGxttRM7qbx/N0VTmlTeuNpLFld8Gtw3fHR8UoLGkH/OTFYPLZBVNE8t/oCCy8FpcCu9SGXxF8vh1R4rq15bfyyh9sBU9RuVtoLM0wDSbKixHhNOwwx2Z/A+SHDaQD9C+x3p1AnS9FYZm0Y07E+VYQWqzOpw
07-28 11:27:38.562: W/System.err(22933): javax.crypto.BadPaddingException: error:0407106B:rsa routines:RSA_padding_check_PKCS1_type_2:block type is not 02
07-28 11:27:41.515: D/WifiNative-wlan0(773): doString: SIGNAL_POLL
07-28 11:27:41.515: W/WifiHW(773): QCOM Debug wifi_send_command "IFNAME=wlan0 SIGNAL_POLL"
07-28 11:27:41.525: D/wpa_supplicant(16189): nl80211: survey data missing!
07-2
07-28 11:27:56.612: W/WifiHW(773): QCOM Debug wifi_send_command "IFNAME=wlan0 SIGNAL_POLL"
07-28 11:27:56.612: D/wpa_supplicant(16189): nl80211: survey data missing!
07-28 11:27:56.622: I/wpa_supplicant(16189): environment dirty rate=0 [0][0][0]
07-28 11:27:56.622: D/WifiStateMachine(773): fetchRssiAndLinkSpeedNative RSSI = -62 abnormalRssiCnt = 0 newLinkSpeed = 58
07-28 11:27:56.622: D/WifiStateMachine(773): fetchRssiAndLinkSpeedNative mLinkspeedCount = 2, mLinkspeedSum: 116


I'm not sure where am going wrong, please help me out.
Thanks .

Answer

A BadPaddingException occurs when the padding (bytes to fill up a too small encryption block) doesn't match a specified format (for example PKCS1, OAEP, ...). This can have a few causes:

  1. You are using a different mode of RSA for en- and decryption.
  2. The data (the byte[]) you get from encryption is not the same as the one you pass to decryption.
  3. (You are using an incorrect KeyPair.)

Since you are initializing RSA with getInstance("RSA") for encryption and getInstance("RSA/ECB/PKCS1Padding") for decryption, it could be possible that ECB/PKCS1Padding is not the default on Android (even though it should be on Desktop-Java).

So try this in RSAEncrypt():

cipher.getInstance("RSA/ECB/PKCS1Padding");

If this does not work, make sure that you pass the exact same byte[] you get from cipher.doFinal() in encryption to cipher.doFinal() in decryption.

(Your code does work on my Desktop Java7 btw.)