Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AES Encryption Java Invalid Key length

I am trying to create an AES encryption method, but for some reason I keep getting

java.security.InvalidKeyException: Key length not 128/192/256 bits

Here is the code:

public static SecretKey getSecretKey(char[] password, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException{
    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
    // NOTE: last argument is the key length, and it is 256
    KeySpec spec = new PBEKeySpec(password, salt, 1024, 256);
    SecretKey tmp = factory.generateSecret(spec);
    SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
    return(secret);
}


public static byte[] encrypt(char[] password, byte[] salt, String text) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, InvalidParameterSpecException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException{
    SecretKey secret = getSecretKey(password, salt);

    Cipher cipher = Cipher.getInstance("AES");

    // NOTE: This is where the Exception is being thrown
    cipher.init(Cipher.ENCRYPT_MODE, secret);
    byte[] ciphertext = cipher.doFinal(text.getBytes("UTF-8"));
    return(ciphertext);
}

Can anyone see what I am doing wrong? I am thinking it may have something to do with the SecretKeyFactory algorithm, but that is the only one I can find that is supported on the end system I am developing against. Any help would be appreciated. Thanks.

like image 384
wuntee Avatar asked Apr 02 '10 19:04

wuntee


People also ask

What is valid AES key length?

Advanced Encryption Standard (AES) keys are symmetric keys that can be three different key lengths (128, 192, or 256 bits). AES is the encryption standard that is recognized and recommended by the US government. The 256-bit keys are the longest allowed by AES.

How long is AES encrypted string?

AES is a block cipher with a block length of 128 bits. AES allows for three different key lengths: 128, 192, or 256 bits. Most of our discussion will assume that the key length is 128 bits.

Which key size is not used by AES?

And they are unequal for AES. 256-bit AES has key schedule vulnerabilities that 128-bit AES does not have. As a result, many (including myself) believe that there is no reason to think 256-bit AES is any stronger than 128-bit AES. I should also point out that AES uses the same block size regardless of key length.

Does the block length have to match the AES key length?

There is no relationship between key size and block size in AES , because it it not a simple XOR . Block size is always 128 bits, but key size can be 128, 192, and 256 bits based on algorithm rounds. AES is a complex algorithm with a lot of steps.


2 Answers

For a stronger key strength encryption you would need to download Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files.

http://java.sun.com/javase/downloads/index.jsp (Check Other Downloads).

like image 87
Mohamed Mansour Avatar answered Oct 24 '22 23:10

Mohamed Mansour


The problem here is the mismatch between key sizes for your key derivation function and the given ciphers. The PBKDF you use is "PBEWithMD5AndDES" and in this string the DES part indicates the type of output. As single DES as it is known uses only 8 byte keys (64 bit, 56 effective bit size with parity bits). AES keys should be either 128, 192 and 256 bit and should not include parity bits.

To create AES strength key sizes you should at least use PBKDF2 instead of PBKDF1, preferably with SHA-256 or SHA-512 for higher key sizes. For 128 bit keys you should however be fine with SHA-1. So use the build in "PBKDF2WithHmacSHA1" SecretKeyFactory instead. Note that PBKDF2 / SHA1 with keys over 160 bit will result in suboptimal operation. You may want to use a simple key based key derivation function (KBKDF) over the output if you want to create more data (such as a separate IV).

As others have indicated, if you use keys of over 128 bit you will need the unlimited crypto jurisdiction files.


Notes on the following code:

  • No integrity protection, which you may need even for maintaining confidentiality
  • CBC using a zero IV, this may be OK but only if the salt is fully random (store the salt with the ciphertext)
  • 1024 is a relatively low number of iterations for the PBKDF2
  • PBKDF2 is incompatible with PBKDF1 which you were using
public static SecretKey getSecretKey(char[] password, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException{
    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    // NOTE: last argument is the key length, and it is 128
    KeySpec spec = new PBEKeySpec(password, salt, 1024, 128);
    SecretKey tmp = factory.generateSecret(spec);
    SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
    return(secret);
}

public static byte[] encrypt(char[] password, byte[] salt, String text) throws GeneralSecurityException {
    SecretKey secret = getSecretKey(password, salt);
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(new byte[cipher.getBlockSize()]));
    byte[] ciphertext = cipher.doFinal(text.getBytes(StandardCharsets.UTF_8));
    return(ciphertext);
}
like image 32
Maarten Bodewes Avatar answered Oct 25 '22 00:10

Maarten Bodewes