How to fix invalid AES key length?

I am working on a text encryption and decryption project (after Struts 2)

Whenever I enter a password and plain text, I get an Invalid AES Key Length error.

Service class

package com.anoncrypt.services; import java.security.Key; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; public class SymAES { private static final String ALGORITHM = "AES"; private static byte[] keyValue= new byte[] { 'T', 'h', 'i', 's', 'I', 's', 'A', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y' }; public String encode(String valueToEnc) throws Exception { Key key = new SecretKeySpec(keyValue, ALGORITHM); Cipher c = Cipher.getInstance(ALGORITHM); c.init(Cipher.ENCRYPT_MODE, key); byte[] encValue = c.doFinal(valueToEnc.getBytes()); String encryptedValue = new BASE64Encoder().encode(encValue); return encryptedValue; } public String decode(String encryptedValue) throws Exception { Key key = new SecretKeySpec(keyValue, ALGORITHM); Cipher c = Cipher.getInstance(ALGORITHM); c.init(Cipher.DECRYPT_MODE, key); byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedValue); byte[] decValue = c.doFinal(decordedValue); String decryptedValue = new String(decValue); return decryptedValue; } public void start(String passcode)throws Exception { keyValue = passcode.getBytes(); } } 

And this is a mistake

 java.security.InvalidKeyException: Invalid AES key length: 6 bytes com.sun.crypto.provider.AESCrypt.init(AESCrypt.java:87) com.sun.crypto.provider.ElectronicCodeBook.init(ElectronicCodeBook.java:93) com.sun.crypto.provider.CipherCore.init(CipherCore.java:582) com.sun.crypto.provider.CipherCore.init(CipherCore.java:458) com.sun.crypto.provider.AESCipher.engineInit(AESCipher.java:307) javax.crypto.Cipher.implInit(Cipher.java:797) javax.crypto.Cipher.chooseProvider(Cipher.java:859) javax.crypto.Cipher.init(Cipher.java:1229) javax.crypto.Cipher.init(Cipher.java:1166) com.anoncrypt.services.SymAES.encode(SymAES.java:35) com.anoncrypt.actions.SymEncrypt.execute(SymEncrypt.java:24) 
+25
java encryption aes
source share
3 answers

What you need to know in general:

  1. Key! = Password
    • SecretKeySpec expects a key, not a password. See below
  2. This may be due to a policy restriction that prevents the use of 32-byte keys. See another answer to this question.

In your case

Problem number 1: you pass the password instead of the key.

AES only supports 16, 24, or 32 byte key sizes. You need to either indicate exactly this amount, or you get a key from what you enter.

There are different ways to get a key from a key phrase. Java provides an implementation of PBKDF2 for this purpose.

I used erickson's answer to paint the whole picture (only encryption, as the decryption is similar, but includes splitting the ciphertext):

 SecureRandom random = new SecureRandom(); byte[] salt = new byte[16]; random.nextBytes(salt); KeySpec spec = new PBEKeySpec("password".toCharArray(), salt, 65536, 256); // AES-256 SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); byte[] key = f.generateSecret(spec).getEncoded(); SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); byte[] ivBytes = new byte[16]; random.nextBytes(ivBytes); IvParameterSpec iv = new IvParameterSpec(ivBytes); Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); c.init(Cipher.ENCRYPT_MODE, keySpec, iv); byte[] encValue = c.doFinal(valueToEnc.getBytes()); byte[] finalCiphertext = new byte[encValue.length+2*16]; System.arraycopy(ivBytes, 0, finalCiphertext, 0, 16); System.arraycopy(salt, 0, finalCiphertext, 16, 16); System.arraycopy(encValue, 0, finalCiphertext, 32, encValue.length); return finalCiphertext; 

Other things to keep in mind:

  • Always use the full name of the cipher. AES not suitable in this case, because different JVM / JCE providers may use different default values ​​for operating mode and populating. Use AES/CBC/PKCS5Padding . Do not use ECB mode because it is not semantically safe.
  • If you are not using ECB mode, you need to send IV along with the ciphertext. This is usually done by adding the IV prefix to the byte array of the ciphertext. An IV is automatically created for you, and you can get it through cipherInstance.getIV() .
  • Whenever you post something, you must be sure that it has not been changed along the way. It is difficult to properly implement encryption using the MAC. I recommend that you use an authentication mode such as CCM or GCM.
+53
source share

You can check the key length restriction:

 int maxKeyLen = Cipher.getMaxAllowedKeyLength("AES"); System.out.println("MaxAllowedKeyLength=[" + maxKeyLen + "]."); 
+3
source share

I had the same problem, after which I made my 16-byte key and now it works fine. Create your key exactly 16 bytes each. This will certainly work.

+2
source share

All Articles