krato
krato

Reputation: 1246

Decrypting string generates IllegalBlockSizeException

I have problems when processing the decrypt method. Encryption is producing a correct output but when I decrypt the exact same encrypted string, (that should be back into plaintext string), it does not work.

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class Samp {

    private static String IV = "aaaaaaaaaaaaaaaa";
    private static final String UNICODE_FORMAT = "UTF8";

    private String padd(String plaintext) {
        while (plaintext.length() % 16 != 0) {
            plaintext += "\0";
        }
        return plaintext;
    }

    public String encryptString(String plaintext, String encryptionKey) {
        try {
            byte[] cipher = encrypt(padd(plaintext), encryptionKey);
            return new String(cipher, UNICODE_FORMAT);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return null;
    }

    public String decryptString(String encString, String encryptionKey) {
        try {
            System.out.println("**** decryptString ****");
            System.out.println("enc = " + encString);
            System.out.println("key = " + encryptionKey);

            String decrypted = decrypt(encString.getBytes(UNICODE_FORMAT), encryptionKey);
            return decrypted;
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return null;
    }

    private static byte[] encrypt(String plainText, String encryptionKey) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "SunJCE");
        SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes(UNICODE_FORMAT), "AES");
        cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(IV.getBytes(UNICODE_FORMAT)));
        return cipher.doFinal(plainText.getBytes(UNICODE_FORMAT));
    }

    private static String decrypt(byte[] cipherText, String encryptionKey) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "SunJCE");
        SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes(UNICODE_FORMAT), "AES");
        cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(IV.getBytes(UNICODE_FORMAT)));
        return new String(cipher.doFinal(cipherText), UNICODE_FORMAT);
    }
    // implement methods here
    // using AES simple encryption

    public static void main(String[] args){
        String plaintext = "Hello World!";
        String key = "asdfqaqwsaerdqsw";

        Samp s = new Samp();
        String enc = s.encryptString(plaintext, key);
        System.out.println("encrypted string = " + enc);
        String dec = s.decryptString(enc, key);
        System.out.println("decrypted string = " + dec);
    }
}

I've already seen this post, which has the same problem as mine. I followed the suggestions(change getBytes() -> getBytes(UNICODE_FORMAT)) but it is still the same. I still get an exception (javax.crypto.IllegalBlockSizeException: Input length not multiple of 16 bytes)

Upvotes: 1

Views: 1398

Answers (3)

user207421
user207421

Reputation: 310903

  public String encryptString(String plaintext, String encryptionKey)

The problem is right here. String is not a container for binary data. This method should return a byte[]. Similarly the decrypt() method should take a byte[] as the ciphertext parameter, not a String.

Upvotes: 3

Chiara Hsieh
Chiara Hsieh

Reputation: 3393

You should use an encoding that is 1 to 1 mapping between characters and bytes, such as "ISO-8859-1". So change your code to

private static final String UNICODE_FORMAT = "ISO-8859-1";

solves the problem.

Upvotes: 1

Scary Wombat
Scary Wombat

Reputation: 44834

here is my code which works

public static String encrypt(String data) throws Exception {

        SecretKeySpec key = generateKey();
        final Cipher c = Cipher.getInstance("AES/EAX/NoPadding", "BC");

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

        byte[] encVal = c.doFinal(data.getBytes("UTF8"));       

        String encryptedValue = Hex.toHexString(encVal);
        return encryptedValue;
    }

    public static String decrypt(String encryptedData) throws Exception {

        Key key = generateKey();
        final Cipher c = Cipher.getInstance("AES/EAX/NoPadding", "BC");

        c.init(Cipher.DECRYPT_MODE, key, ivSpec);
        byte[] ba = Hex.decode(encryptedData);

        byte[] encVal = c.doFinal(ba);  

        return new String (encVal);

    }

Upvotes: 0

Related Questions