Reputation: 34424
When running below programme i am getting this exception. Not able to figure out what the issue as AES allows the 128 -256 bit key?
Exception in thread "main" java.security.InvalidKeyException: Invalid AES key length: 29 bytes
at com.sun.crypto.provider.AESCipher.engineGetKeySize(DashoA13*..)
at javax.crypto.Cipher.b(DashoA13*..)
Getting exception at line 20
Here is the programme
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class AESEncryptionDecryptionTest {
private static final String ALGORITHM = "AES";
private static final String myEncryptionKey = "ThisIsSecurityKey";
private static final String UNICODE_FORMAT = "UTF8";
public static String encrypt(String valueToEnc) throws Exception {
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGORITHM);
c.init(Cipher.ENCRYPT_MODE, key); //////////LINE 20
byte[] encValue = c.doFinal(valueToEnc.getBytes());
String encryptedValue = new BASE64Encoder().encode(encValue);
return encryptedValue;
}
public static String decrypt(String encryptedValue) throws Exception {
Key key = generateKey();
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;
}
private static Key generateKey() throws Exception {
byte[] keyAsBytes;
keyAsBytes = myEncryptionKey.getBytes(UNICODE_FORMAT);
Key key = new SecretKeySpec(keyAsBytes, ALGORITHM);
return key;
}
public static void main(String[] args) throws Exception {
String value = "password1";
String valueEnc = AESEncryptionDecryptionTest.encrypt(value);
String valueDec = AESEncryptionDecryptionTest.decrypt(valueEnc);
System.out.println("Plain Text : " + value);
System.out.println("Encrypted : " + valueEnc);
System.out.println("Decrypted : " + valueDec);
}
}
Upvotes: 14
Views: 65606
Reputation: 8865
The key uses randomness as input, but there are stiill requirements for how it is composed. The SecretKeySpec
constructor you used is for loading an already generated key into memory. Instead, use KeyGenerator
.
KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM);
kg.init(128);
SecretKey k = kg.generateKey();
Also note that AES-128 is now actually thought to be weaker than AES-256. It probably isn't drastically different but the benefit from the longer key size may be outweighed by simplifications elsewhere (fewer rounds).
Upvotes: 1
Reputation: 18405
AES allows 128, 192 or 256 bit key length. That is 16, 24 or 32 byte. Try taking just the first 16 bytes of your mEncryptionKey
as the keyAsBytes
.
Edit:
An after though occurred to me. A habit I have formed, and one which I recommend, is to take a SHA hash of a password/passphrase, and use that as the source bytes of your key. Taking a hash guarantees the key data will be the correct size, irrespective of the length of the password/passphrase. Your current implementation of using the String bytes has two problems;
Both of these problems are eliminated by using a hash.
Take a look at the buildKey()
method in this class; https://github.com/qwerky/DataVault/blob/master/src/qwerky/tools/datavault/DataVault.java
Upvotes: 32