Home > other >  PHP AES-256-CBC encrypted data is different from JAVA AES/CBC/PKCS5PADDING
PHP AES-256-CBC encrypted data is different from JAVA AES/CBC/PKCS5PADDING

Time:07-12

I have a java code working perfectly

public static String encrypt(String message, String sercretKey)
    {
        String base64EncryptedString = "";
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] digestOfPassword = md.digest(sercretKey.getBytes("utf-8"));
            byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
            byte[] iv = Arrays.copyOf(digestOfPassword, 16);
            SecretKey key = new SecretKeySpec(keyBytes, "AES");
            javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
            cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, key, ivParameterSpec);
            byte[] plainTextBytes = message.getBytes("utf-8");
            byte[] buf = cipher.doFinal(plainTextBytes);
            byte[] base64Bytes = Base64.getEncoder().encode(buf);
            base64EncryptedString = new String(base64Bytes);
        return base64EncryptedString;
    }

I have tried using below code to recreate this above code in PHP

function encryptTest($sSecretKey,$sValue)
        {
            $key = hash('sha256', $sSecretKey,false);
            $key = utf8_encode($key);
            $key = substr($key, 0, 24);
            $iv = substr($key, 0, 16);
            $data = $sValue;
            $outEnc = openssl_encrypt($data, "AES-256-CBC", $key, OPENSSL_RAW_DATA, $iv);
            
            return base64_encode($outEnc);
        }

But showing different results. What I have missed.

(Same types of questions are available in StackOverflow, but pointing my issues)

CodePudding user response:

There are the following issues:

  • In the PHP code, the key is currently returned hex encoded. Instead, it must be returned as bytes string. To do this, the third parameter in hash() must be switched from false to true.
  • In the Java code a 192 bits key is used, i.e. AES-192. Accordingly, in the PHP code "AES-192-CBC" must be applied (and not "AES-256-CBC").
  • The utf8_encode() call in the PHP code is to be removed, as this corrupts the key.

With these changes, both codes provide the same ciphertext.

Security:
Using SHA256 as key derivation is insecure. Instead apply a dedicated algorithm like Argon2 or PBKDF2. Also, using the key (or a part of it) as IV is insecure as it results in the reuse of key/IV pairs. Instead, a randomly generated IV should be applied for each encryption.

  • Related