Search code examples
pythonphpencryptionaes

AES-256-CBC encryption returning different result in Python and PHP , HELPPP


Python Code:

     from Crypto.Random import get_random_bytes
     from Crypto.Cipher import AES
     from Crypto.Util.Padding import pad
     import base64

     def encrypt_string(input_string, key_base64, str_iv):
         try:
            key = key_base64.encode('utf-8')
        
            if str_iv:
               iv = base64.b64decode(str_iv)
            else:
               iv = get_random_bytes(16)

            cipher = AES.new(key, AES.MODE_CBC, iv)
            padded_data = pad(input_string.encode(), AES.block_size)
            cipher_data = cipher.encrypt(padded_data)
            combined_data = iv + cipher_data
            return base64.b64encode(combined_data).decode()

         except Exception as e:
            print(e)

    if __name__ == "__main__":
        key = "1bd393e7a457f9023d9ba95fffb5a2e1"
        iv = "1oTOhV9xGyu1mppmWZWa5w=="
        input_string = "AAAAAAA"
        encrypted_data = encrypt_string(input_string, key, iv)
        print("Encrypted string:", encrypted_data)`

OUTPUT : Encrypted string: 1oTOhV9xGyu1mppmWZWa5+kzveiTRzRH+gRVHx+7Ad0=

PHP code:

      <?php
       function encrypt_string($input_string, $key_base64, $str_iv) {
        try {
         $key = base64_decode($key_base64);

        if ($str_iv) {
            $iv = base64_decode($str_iv);
        } else {
            $iv = openssl_random_pseudo_bytes(16);
        }
        $ciphertext = openssl_encrypt($input_string, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
        $combined_data = $iv . $ciphertext;
        return base64_encode($combined_data);
       } catch (Exception $e) {
        echo $e->getMessage();
       }
      }
      $key = "1bd393e7a457f9023d9ba95fffb5a2e1";
       $iv = "1oTOhV9xGyu1mppmWZWa5w==";
       $input_string = "AAAAAAA";
       $encrypted_data = encrypt_string($input_string, $key, $iv);
       echo "Encrypted string: " . $encrypted_data . "\n";
      ?>

OUTPUT: Encrypted string: 1oTOhV9xGyu1mppmWZWa53Nc8rxWTultBWLvWitUICQ=

Please, does anyone know how to make the output of these two codes the same?


Solution

  • If you want to get the same result then just remove the $key = base64_decode($key_base64). I did get the right result for $key = $key_base64.


    Note that using the base64 encoding directly as key means that a maximum of 6 bits contain random information for each character / byte of input. So if you insert 32 characters then the key size is effectively 32 * 6 = 192 bits. That's more than enough, but clearly less than the 256 bits "promised" by AES-256.

    The other issue is that CBC doesn't offer integrity / authenticity.


    I'd recommend never to convert keys to strings in the first place - just keep them binary. Furthermore, if you're going to encrypt with a symmetric key then use something like NaCL or another library that performs higher level "sealing" rather than just encryption. If you want to use a password then you should use a good Password Based Key Derivation Function (PBKDF) such as PBKDF2 or Argon2.