Karthik Sivam Karthik Sivam - 1 year ago 397
Android Question

javax.crypto.IllegalBlockSizeException: last block incomplete in decryption

I'm working on a android project in which I have to decrypt string from a file in PHP server, encryption was done using PHP.(AES 128 algorithm)

Encryption Code:

function aes128Encrypt($key, $data) {
$key = md5($key);
return mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, str_repeat("\0", 16));

My code for getting string from URL:

String myUri = "http://www.example.com/lib2.php";
HttpClient httpClient = new DefaultHttpClient();
HttpGet get = new HttpGet(myUri);

HttpResponse response = httpClient.execute(get);

String bodyHtml = "";
String xmlFile = "";
bodyHtml = EntityUtils.toString(response.getEntity());
xmlFile = decrypt(bodyHtml);

decrypt() method:

public static String decrypt(String encData) throws Exception
Key key = generateKey();

Cipher c = Cipher.getInstance(algo + "/CBC/PKCS7Padding");

//Cipher c = Cipher.getInstance(algo);

IvParameterSpec ivSpec = new IvParameterSpec(ivbytes);

c.init(Cipher.DECRYPT_MODE, key , ivSpec);

//byte[] decValue = Base64.decode(encData , Base64.NO_PADDING);

//byte[] decFin = Base64.decode(decValue, Base64.NO_PADDING);

//byte[] decFinal = c.doFinal(decValue);

byte[] decFinal = c.doFinal(encData.getBytes());

String getAns = new String(decFinal, "UTF8");

return getAns;

In generateKey():

public static Key generateKey()

try {
MessageDigest digest = java.security.MessageDigest


key1 = digest.digest();

} catch (NoSuchAlgorithmException e) {

Key key = new SecretKeySpec(key1,algo);
return key;

The Logcat shows below exception:

javax.crypto.IllegalBlockSizeException: last block incomplete in decryption

at the line

The Codes I'v commented out are also the codes I'v used to check. What is wrong with this code?. Any help will be appreciated.

Answer Source

The problem probably is the way you treat the value from the PHP server as a Java String. The PHP mcrypt_encrypt function returns a binary string, where each byte can have any value. PHP mcrypt_encrypt does not use any character encoding. So using EntityUtils.toString() is already an error - and using String.getBytes() without specifying the encoding generally is as well.

You just need to use either getContent() or writeTo(OutputStream outstream) to get the the binary ciphertext. If you opt for the first option, you can wrap a CipherInputStream around it. Initialize it with the "AES/CBC/NoPadding" cipher and you can directly decrypt the plain text string. Beware that you may have to trim a certain number of 00 valued bytes from the result to get to the plaintext.