Encrypting using AES-256, can I use 256 bits IV?

The IV depends on the mode of operation. For most modes (e.g. CBC), the IV must have the same length as the block. AES uses 128-bit blocks, so a 128-bit IV. Note that AES-256 uses a 256-bit key (hence the name), but still with 128-bit blocks.

AES was chosen as a subset of the family of block ciphers known as Rijndael. That family includes no less than 15 variants, for three possible block sizes (128, 192 and 256 bits) and five possible key sizes (128, 160, 192, 224 and 256 bits). AES, as standardized by NIST, includes only three variants, all with 128-bit blocks, and with keys of 128, 192 or 256 bits.

To further confuse things, some software frameworks got it wrong; e.g. PHP uses "MCRYPT_RIJNDAEL_128" to designate Rijndael with 128-bit keys and 128-bit blocks (i.e. the same thing as AES-128), and "MCRYPT_RIJNDAEL_256" for Rijndael with 256-bit keys and 256-bit blocks (i.e. not one of the AES variants, and in particular not at all AES-256).


The IV handling in Java is dependent on the cryptographic provider that is used. The SUN provider that comes with the OpenJDK / Oracle runtimes is rather strict; it requires the IV to be the same size as the block size for most modes of operation. This is true even for CTR mode where you might have expected that supplying a nonce - the first / leftmost bytes of the counter - should be sufficient. ECB mode of course does not require an IV, so it will throw an exception if you try and supply one.

The block size of AES is always 128 bits, so a 256 bit IV is not possible for most modes of operation. As already noted in a few answers, Rijndael can be configured with a block size of 256 bit, but Rijndael is not included in the standard runtime. You would need an additional provider or library such as Bouncy Castle to use Rijndael. The block cipher AES doesn't use an IV as input, which is also why supplying an IV for ECB mode fails. Some other languages/runtimes simply ignore the IV for ECB

Now there is one cipher that does allow you to specify a 256 bit IV (or actually: nonce) and that is GCM. GCM works best with a nonce of 12 bytes though. GCM converts data - includes the nonce - to a 128 bit counter for CTR mode internally.

Note that increasing the IV size does not auto-magically make the algorithm more secure. If you have 256 bit input for an IV then you could use SHA-256 bit on the input and take the 128 leftmost bits instead.


As we were talking Java, here's some code, you can fiddle with the IV size and try some algorithms such as "AES/CFB/NoPadding" yourself. Note that the static IV's used in the code are for demonstration purposes only. CTR requires a unique IV, CBC requires a fully unpredictable IV (which is commonly fulfilled by randomizing all 16 bytes for AES).

SecretKey aesKey = new SecretKeySpec(new byte[256 / Byte.SIZE], "AES");
byte[] pt = "owlstead".getBytes(StandardCharsets.US_ASCII);

{
    // === CBC mode requires an IV of the same size as the block size
    Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
    // changing the IV size will result in an exception
    byte[] ivBytes = new byte[c.getBlockSize()];
    IvParameterSpec iv = new IvParameterSpec(ivBytes);
    c.init(Cipher.ENCRYPT_MODE, aesKey, iv);
    byte[] ct = c.doFinal(pt);
    System.out.println(Hex.toHexString(ct));
}

{
    // === CTR mode actually requires a complete IV in Java
    // Java (or actually, the SUN provider) requires a 128 bit IV instead of just a nonce
    Cipher c = Cipher.getInstance("AES/CTR/NoPadding");
    // changing the IV size will result in an exception
    byte[] ivBytes = new byte[c.getBlockSize()];
    IvParameterSpec iv = new IvParameterSpec(ivBytes);
    c.init(Cipher.ENCRYPT_MODE, aesKey, iv);
    byte[] ct = c.doFinal(pt);
    System.out.println(Hex.toHexString(ct));
}

{
    // === GCM mode can do it!
    Cipher c = Cipher.getInstance("AES/GCM/NoPadding");
    byte[] ivBytes = new byte[256 / Byte.SIZE];
    GCMParameterSpec gcmSpecWithIV = new GCMParameterSpec(128, ivBytes);
    c.init(Cipher.ENCRYPT_MODE, aesKey, gcmSpecWithIV);
    byte[] ct = c.doFinal(pt);
    System.out.println(Hex.toHexString(ct));
}

{
    // ===  java.security.InvalidAlgorithmParameterException: ECB mode cannot use IV
    Cipher c = Cipher.getInstance("AES/ECB/PKCS5Padding");
    byte[] ivBytes = new byte[c.getBlockSize()];
    IvParameterSpec iv = new IvParameterSpec(ivBytes);
    c.init(Cipher.ENCRYPT_MODE, aesKey, iv);
    byte[] ct = c.doFinal(pt);
    System.out.println(Hex.toHexString(ct));
}

You must use a 128 bit IV. For CBC mode IV must match the block size, which is always 128 bits for AES.

Rijndael, the winning AES candidate, is defined for 128 and 256 bit blocks, but only 128 bit blocks were standardized as AES. Some libraries support Rijndael with 256 bit blocks, but then you're no longer using AES.

If you need a longer IV for some reason, you can use a KDF or hash to turn the original key and the IV into the key you actually use for AES.