Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cipher: What is the reason for IllegalBlockSizeException?

I have observed the following when I worked with Cipher.

Encryption code:

Cipher aes = Cipher.getInstance("AES");
aes.init(Cipher.ENCRYPT_MODE, generateKey());
byte[] ciphertext = aes.doFinal(rawPassword.getBytes());

Decryption code :

Cipher aes = Cipher.getInstance("AES");
aes.init(Cipher.DECRYPT_MODE, generateKey());
byte[] ciphertext = aes.doFinal(rawPassword.getBytes());

I get IllegalBlockSizeException ( Input length must be multiple of 16 when ...) on running the Decrypt code.

But If I change the decrypt code to

Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding"); //I am passing the padding too
aes.init(Cipher.DECRYPT_MODE, generateKey());
byte[] ciphertext = aes.doFinal(rawPassword.getBytes());

It works fine. I understand that it is in the pattern algorithm/mode/padding. So I thought it is because I didn't mention the padding. So I tried giving mode and padding during encryption,

Encryption code:

Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding");//Gave padding during encryption too
aes.init(Cipher.ENCRYPT_MODE, generateKey());
byte[] ciphertext = aes.doFinal(rawPassword.getBytes());

Decryption code :

Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding");
aes.init(Cipher.DECRYPT_MODE, generateKey());
byte[] ciphertext = aes.doFinal(rawPassword.getBytes());

But it fails with IllegalBlockSizeException.

What is the reason, why the exception and what is exactly happening underneath. If anyone can help? Thanks in advance

UPDATE

Looks like the issue is with the string I am encrypting and decrypting. Because, even the code that I said works, doesn't always work. I am basically encrypting UUIDs (eg : 8e7307a2-ef01-4d7d-b854-e81ce152bbf6). It works with certain strings and doesn't with certain others.

The length of encrypted String is 64 which is divisible by 16. Yes, I am running it on the same machine.

Method for secret key generation:

    private Key generateKey() throws NoSuchAlgorithmException {
    MessageDigest digest = MessageDigest.getInstance("SHA");
            String passphrase = "blahbl blahbla blah";
    digest.update(passphrase.getBytes());
    return new SecretKeySpec(digest.digest(), 0, 16, "AES");
}
like image 236
shazinltc Avatar asked Apr 24 '13 12:04

shazinltc


2 Answers

During decryption, one can only get an IllegalBlockSizeException if the input data is not a multiple of the block-size (16 bytes for AES).

If the key or the data was invalid (but correct in length), you would get a BadPaddingException because the PKCS #5 padding would be wrong in the plaintext. Very occasionally the padding would appear correct by chance and you would have no exception at all.


N.B. I would recommend you always specify the padding and mode. If you don't, you are liable to be surprised if the provider changes the defaults. AFAIK, the Sun provider converts "AES" to "AES/ECB/PKCS5Padding".

like image 151
Duncan Jones Avatar answered Nov 20 '22 17:11

Duncan Jones


Though I haven't fully understood the internals, I have found what the issue is.

I fetch the encrypted string as a GET request parameter. As the string contains unsafe characters, over the request the string gets corrupted. The solution is, to do URL encoding and decoding.

I am able to do it successfully using the URLEncoder and URLDecoder.

Now the results are consistent. Thanks :)

I would be grateful if anyone can contribute more to this.

like image 6
shazinltc Avatar answered Nov 20 '22 15:11

shazinltc