Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android AES and init vector

I have an issue with AES encryptio and decryption: I can change my IV entirely and still I'm able to decode my data.

public static final byte[] IV = { 65, 1, 2, 23, 4, 5, 6, 7, 32, 21, 10, 11, 12, 13, 84, 45 };
public static final byte[] IV2 = { 65, 1, 2, 23, 45, 54, 61, 81, 32, 21, 10, 121, 12, 13, 84, 45 };
public static final byte[] KEY = { 0, 42, 2, 54, 4, 45, 6, 7, 65, 9, 54, 11, 12, 13, 60, 15 };
public static final byte[] KEY2 = { 0, 42, 2, 54, 43, 45, 16, 17, 65, 9, 54, 11, 12, 13, 60, 15 };
//public static final int BITS = 256;

public static void test()
{
    try
    {
        // encryption
        Cipher c = Cipher.getInstance("AES");
        SecretKeySpec keySpec = new SecretKeySpec(KEY, "AES");
        c.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(IV));

        String s = "Secret message";
        byte[] data = s.getBytes();

        byte[] encrypted = c.doFinal(data);

        String encryptedStr = "";
        for (int i = 0; i < encrypted.length; i++)
            encryptedStr += (char) encrypted[i];


        //decryoption
        Cipher d_c = Cipher.getInstance("AES");
        SecretKeySpec d_keySpec = new SecretKeySpec(KEY, "AES");
        d_c.init(Cipher.DECRYPT_MODE, d_keySpec, new IvParameterSpec(IV2));

        byte[] decrypted = d_c.doFinal(encrypted);
        String decryptedStr = "";
        for (int i = 0; i < decrypted.length; i++)
            decryptedStr += (char) decrypted[i];
        Log.d("", decryptedStr);

    }
    catch (Exception ex)
    {
        Log.d("", ex.getMessage());
    }
}

Any ideas what I'm doing wrong? How can I get 256 bit AES encryption (only change key to 32-byte long array?)

Encryption is a new topic for me so please for newbie friendly answers.

like image 601
Tomasz Wójcik Avatar asked Mar 18 '11 15:03

Tomasz Wójcik


1 Answers

You aren't specifying a cipher mode, so the provider is probably defaulting to Electronic Code Book mode ("ECB") and ignoring the IV completely. You can verify this by comparing the cipher text produced by several runs of your program; I'm guessing that they are all identical.

Cipher-block chaining ("CBC") is commonly supported and widely used, but the right mode depends on your application.

You aren't specifying padding either, so the provider is picking a default. What the JCE calls "PKCS5Padding" is a common choice for symmetric ciphers.

Instead of specifying "AES" as the algorithm, provide a complete specification including algorithm, mode, and padding, like "AES/CBC/PKCS5Padding".

You don't have to specify the AES key size in the Cipher name; it is inferred from the size of the key that you use to initialize the cipher.

like image 161
erickson Avatar answered Oct 29 '22 19:10

erickson