0
votes

I'm trying to implement encrypt with AES/128/CBC, but I need to encrypt with a 64 bytes key, But I have the problem with the length.

It is possible encrypt AES/128/CBC with a 64 bytes key or not, because I have the cipher algoritm in php with a 64 bytes key and it works, but not in java.

This is the encrypt code:

 public static String ALGORITHM = "AES";

 public static String AES_CBC_PADDING = "AES/CBC/PKCS5Padding";

 public static byte[] encrypt(final byte[] key, final byte[] IV, final byte[] message) throws Exception {
  return AESManager.encryptDecrypt(Cipher.ENCRYPT_MODE, key, IV, message);
 }

 public static byte[] decrypt(final byte[] key, final byte[] IV, final byte[] message) throws Exception {
  return AESManager.encryptDecrypt(Cipher.DECRYPT_MODE, key, IV, message);
 }

 private static byte[] encryptDecrypt(final int mode, final byte[] key, 
                                    final byte[] IV, final byte[] message) throws Exception {
  final Cipher cipher = Cipher.getInstance(AES_CBC_PADDING);
  final SecretKeySpec keySpec = new SecretKeySpec(key, ALGORITHM);
  final IvParameterSpec ivSpec = new IvParameterSpec(IV);
  cipher.init(mode, keySpec, ivSpec);
  return cipher.doFinal(message);
 }

 public static String getHex(byte[] data, int length) {
  StringBuffer sb = new StringBuffer();
  for (int i = 0; i < length; i++) {
   String hexStr = Integer.toHexString(((int) data[i]) & 0xFF);
   if (hexStr.length() < 2) {
    sb.append("0").append(hexStr.toUpperCase());
   } else {
    sb.append(hexStr.toUpperCase());
   }
  }
  return sb.toString();
 }

I have this error:

java.security.InvalidKeyException: Invalid AES key length: 64 bytes
at com.sun.crypto.provider.AESCrypt.init(AESCrypt.java:87)
at com.sun.crypto.provider.CipherBlockChaining.init(CipherBlockChaining.java:93)
at com.sun.crypto.provider.CipherCore.init(CipherCore.java:591)
at com.sun.crypto.provider.AESCipher.engineInit(AESCipher.java:346)
at javax.crypto.Cipher.implInit(Cipher.java:805)
at javax.crypto.Cipher.chooseProvider(Cipher.java:863)
at javax.crypto.Cipher.init(Cipher.java:1395)
at javax.crypto.Cipher.init(Cipher.java:1326)
at ec.otecel.tuenti.balance.util.AESManager.encryptDecrypt(AESManager.java)
at ec.otecel.tuenti.balance.util.AESManager.encrypt(AESManager.java)
at ec.otecel.tuenti.balance.util.FreemiumUtil.ciphertoFreemium(FreemiumUtil.java)
at ec.otecel.tuenti.balance.util.FreemiumUtil.main(FreemiumUtil.java)

I have local_policy.jar and US_export_policy.jar in C:\Program Files\Java\jdk1.8.0_241\jre\lib\security so, what could be the problem ?

2
I have the cipher algorithm in php with a 64 bytes key and it works... I see no php code in your question, nor even a hint on what it's doing. - President James K. Polk

2 Answers

3
votes

AES-128 requires a 16 byte key. The "128" in "AES-128" is the key size in bits. Divide by 8 to get the key size in bytes == 16 bytes.

I have the cipher algorithm in php with a 64 bytes key and it works

I am.... skeptical. I suspect it's somehow deriving a 16 byte key from the 64 bytes.

1
votes

As stated by @dnault the en-/decryption key for AES-128 is 16 bytes long (AES-192 = 24 bytes, AES-256 = 32 bytes). You wrote that you are presenting a 64 character long key to the decryption method in PHP. My sample program shows that only the first 16 characters of the key were used.

Solution for your Java-app: just use the first (seen from the left side) 16 bytes of your "key" for encryption and decryption:

<?php
    // https://stackguides.com/questions/62562417/aes-128-cbc-cipher-in-java/62562813#62562813
    $method = "AES-128-CBC";
    $plaintext = "Hello World";
    $key = "1234567890123456789012345678901234567890123456789012345678901234";
    var_dump($key);
    $iv =  "\x08\x07\x05\x06\x04\x01\x02\x03\x12\x11\x0f\x10\x0e\x0b\x0c\x0d";
    $encrypted = base64_encode(openssl_encrypt($plaintext, $method, $key, OPENSSL_RAW_DATA, $iv));
    echo 'encrypted with key ' . $key . ' is ' . $encrypted . '<br>'. PHP_EOL;
    // truncated key = first 16 characters as for aes-128-cbc
    $key = "1234567890123456";
    var_dump($key);
    $encrypted = base64_encode(openssl_encrypt($plaintext, $method, $key, OPENSSL_RAW_DATA, $iv));
    echo 'encrypted with key ' . $key . ' is ' . $encrypted . '<br>'. PHP_EOL;
?>

Result:

string(64) "1234567890123456789012345678901234567890123456789012345678901234"
encrypted with key 1234567890123456789012345678901234567890123456789012345678901234 is iLaK2e4sWLOb0KfGy7ZRsQ==<br>
string(16) "1234567890123456"
encrypted with key 1234567890123456                                                 is iLaK2e4sWLOb0KfGy7ZRsQ==<br>