0

I have two applications, one writen in C#, the other in PHP.

C# application encrypt messages using AES 256 CBC. Key used for encrypt is located in a byte[] property hardcoded in the class. The Initialization vector is also hardcoded and is the same through the time.

C# Application

byte[] key  = {142, 237, ....};
byte[] InitilizationVector  = {132, ...};
var mensajeSinEncriptar = "";

SymmetricAlgorithm algoritmo = SymmetricAlgorithm.Create("Rijndael");
algoritmo.BlockSize = 128;
algoritmo.Mode = CipherMode.CBC;
algoritmo.Padding = PaddingMode.Zeros;
algoritmo.KeySize = 256;
algoritmo.Key = key;
algoritmo.IV = InitilizationVector;

ICryptoTransform encriptador  = algoritmo.CreateEncryptor();
byte[] textoPlano = Encoding.Default.GetBytes(mensajeSinEncriptar);
MemoryStream memoryStream = new MemoryStream();

CryptoStream cryptoStream = new CryptoStream(memoryStream, encriptador, CryptoStreamMode.Write);
cryptoStream.Write(textoPlano, 0, textoPlano.Length);
cryptoStream.FlushFinalBlock();

memoryStream.Close();
cryptoStream.Close();

return Convert.ToBase64String(memoryStream.ToArray());

Then, in my PHP application I want to decrypt the messages generated by c # using OpenSSL. I use the same key and iv used in C#. I convert them to characters because the function does not accept anything other than string.

PHP

    private function decrypt(string $message)
    {
        $stringOf = function ($bytes) {
            return implode('', array_map('chr', $bytes));
        };

        $key = [142, 237, ...];
        $iv  = [132, ... ];

        $result = openssl_decrypt(
            base64_decode($message), 
            'aes-256-cbc', 
            $stringOf($key), 
            1, 
            $stringOf($iv)
        );

        if (is_bool($result) && !$result) {
            return new Error('Error: ' . openssl_error_string());
        }

        return $result;
    }

When I try to decrypt I get this error

Error: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt

I guess it's a mistake of mine when trying to convert the key to a string. Since I also have a function to encrypt which gives me different results using the same key and iv used in C#.

4
  • I had the same problem but the other way around. Long story short, the array lengths are different in php and C# so the key ends up being different Commented Feb 5, 2020 at 12:33
  • 2
    In the C# code Zero-padding is applied, in the PHP code PKCS7 padding (the default). Use a consistent padding in both codes, preferably PKCS7, as it is more reliable. Commented Feb 5, 2020 at 15:41
  • @Topaco You're right, I was using a different padding mode on each one. I can't change the padding in c # because the app is in production. When decrypting the message in PHP with the OPENSSL_ZERO_PADDING flag, the library returns the decrypted message, but adds bar characters at the end of the text string. For example "mymessage /////". Commented Feb 6, 2020 at 9:14
  • 2
    Since openssl_... doesn't support Zero-padding, the only option is to disable PKCS7-padding for decryption. This is done with OPENSSL_ZERO_PADDING. Note that the flag doesn't enable Zero-padding (the name isn't well chosen). As a result, the 0-values of the Zero-padding remain, which must be removed manually (e.g. with rtrim($decrypted,"\0");). However, if the unpadded ciphertext already ends with 0-values, these would be removed as well because the information is missing how many bytes to remove. This is different for PKCS7-padding, that's why it is more reliable than Zero-padding. Commented Feb 6, 2020 at 9:52

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.