Search code examples
phpopensslaes

Generation of symetric key AES-256-CBC with PHP & OpenSSL


Anyone knows how to generate symetric key AES-256-CBC with OpenSSL. I generate IV with openssl_random_pseudo_bytes function. I tried to use openssl_encrypt - but it doesn't work. I found implementation of it on the web, but in Java language.

KeyGenerator keyGenerator = KeyGenerator.getInstance("AES") ;
keyGenerator.init(256);
SecretKey secretKey = keyGenerator.generateKey() ;
return secretKey.getEncoded();

Solution

  • The random generation of an AES encryption key works exact the same as for the initialization vector by using "openssl_random_pseudo_bytes" function.

    Below you find a full running example for an AES 256 CBC encryption of a string with randomly generated key and IV. As you need the same IV for decryption the output is (Base64 encoded) IV : (Base64 encoded) ciphertext - in real programs you would concatenate both on binary basis before encoding.

    This is the output:

    AES CBC 256 String encryption with random key full
    plaintext: The quick brown fox jumps over the lazy dog
    encryptionKey (Base64): wJknn3c1MHWhDQaqCVYU648EbkdxIVjWghiJoXrpva8=
    
    * * * Encryption * * *
    ciphertext: s7L1BK/ds97P+abbuHtNUA==:5hWlNtTdEUgjQTkOVWV/QG2RauFjXNWwr+2Dczgx55pTg4azuNhwZyTFhyYFQSVh
    output is (Base64) iv : (Base64) ciphertext
    
    Cross platform cryptography: AES CBC 256 String encryption with random key (PHP)
    
    * * * Decryption * * *
    decryptionKey (Base64): JJu2xyi4sP7lTfxVi8iPvKIIOWiwkgr7spyUEhsnjek=
    ciphertextDecryption (Base64): +KOM4ASOY0cMNrM9zV/qvw==:HuoyDiusSplYfd04XSNLOqtcWyOFwmeHNzXS5ywmqRkgAXi8do/6dKppo2U3ZoKl
    input is (Base64) iv : (Base64) ciphertext
    plaintext: The quick brown fox jumps over the lazy dog
    

    Kindly note that the code has not exception handling and is for educational purpose only.

    <?php
    function generateRandomAesKey()
    {
        return openssl_random_pseudo_bytes(32, $crypto_strong);
    }
    
    function generateRandomInitvector()
    {
        return openssl_random_pseudo_bytes(16, $crypto_strong);
    }
    
    function base64Encoding($input)
    {
        return base64_encode($input);
    }
    
    function base64Decoding($input)
    {
        return base64_decode($input);
    }
    
    function aesCbcEncryptToBase64($key, $data)
    {
        $iv = generateRandomInitvector();
        $ciphertext = openssl_encrypt($data, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
        return base64_encode($iv) . ':' . base64_encode($ciphertext);
    }
    
    function aesCbcDecryptFromBase64($key, $data)
    {
        list($iv, $encryptedData) = explode(':', $data, 2);
        return openssl_decrypt(base64_decode($encryptedData), 'aes-256-cbc', $key, OPENSSL_RAW_DATA, base64_decode($iv));
    }
    
    echo 'AES CBC 256 String encryption with random key full' . PHP_EOL;
    
    $plaintext = 'The quick brown fox jumps over the lazy dog';
    echo 'plaintext: ' . $plaintext . PHP_EOL;
    
    // generate random key
    $encryptionKey = generateRandomAesKey();
    $encryptionKeyBase64 = base64Encoding($encryptionKey);
    echo 'encryptionKey (Base64): ' . $encryptionKeyBase64 . PHP_EOL;
    
    // encryption
    echo PHP_EOL . '* * * Encryption * * *' . PHP_EOL;
    $ciphertextBase64 = aesCbcEncryptToBase64($encryptionKey, $plaintext);
    echo 'ciphertext: ' . $ciphertextBase64 . PHP_EOL;
    echo 'output is (Base64) iv : (Base64) ciphertext' .PHP_EOL;
    
    echo PHP_EOL;
    echo 'Cross platform cryptography: AES CBC 256 String encryption with random key (PHP)' . PHP_EOL;
    // decryption
    echo PHP_EOL . '* * * Decryption * * *' . PHP_EOL;
    $decryptionKeyBase64 = $encryptionKeyBase64;
    $ciphertextDecryptionBase64 = $ciphertextBase64;
    echo 'decryptionKey (Base64): ' . $decryptionKeyBase64 . PHP_EOL;
    
    echo 'ciphertextDecryption (Base64): ' . $ciphertextDecryptionBase64 . PHP_EOL;
    echo 'input is (Base64) iv : (Base64) ciphertext' .PHP_EOL;
    $decryptionKey = base64Decoding($decryptionKeyBase64);
    $decryptedtext = aesCbcDecryptFromBase64($decryptionKey, $ciphertextDecryptionBase64);
    echo 'plaintext: ' . $decryptedtext . PHP_EOL;
    ?>