Search code examples
phpencryptionopensslmcryptdes

How to encrypt with openSSL using the DES-CBC method


Actually I'm using Mcrypt but I'm moving to OpenSSL and I need to be able to use it the exact same way as Mcrypt.

This is how I'm encrypting

mcrypt_encrypt(MCRYPT_DES, $key, $text, MCRYPT_MODE_cbc, "\0\0\0\0\0\0\0\0");

For the decryption, I already managed to do it in OpenSSL, both are working the same exact ways

//Using Mcrypt
mcrypt_decrypt(MCRYPT_DES, $key, $enc, MCRYPT_MODE_cbc, "\0\0\0\0\0\0\0\0");

//Using Openssl
openssl_decrypt($enc, 'des-cbc', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); 

For the encryption using OpenSSL, this is my test code

$key = "123456SO";
$text = "name=louis&cp=75013";

$encMcrypt = mcrypt_encrypt(MCRYPT_DES, $key, $text, MCRYPT_MODE_cbc, "\0\0\0\0\0\0\0\0");
$encOpenssl = openssl_encrypt($text, "des-cbc", $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, "\0\0\0\0\0\0\0\0");

echo "Mcrypt : " . urlencode(base64_encode($encMcrypt));
echo " OpenSsl : " . urlencode(base64_encode($encOpenssl));

And this is the output :

Mcrypt : f0tF0ERITdKiI2SxrttYAJBVNBtoGR%2BD OpenSsl :

This is the official list of methods, but I can't find the DES methods.

I know that OpenSSL declared DES weak, but I still need to use it in my situation.

How can I encrypt in DES-CBC using OpenSSL and make it behave the same way as the Mcrypt function?

Edit:

If I removed the OPENSSL_ZERO_PADDING option, the result is almost the one expected

Code:

openssl_encrypt($text, "des-cbc", $key, OPENSSL_RAW_DATA , "\0\0\0\0\0\0\0\0");

output:

Mcrypt  : f0tF0ERITdKiI2SxrttYAJBVNBtoGR%2BD
OpenSsl : f0tF0ERITdKiI2SxrttYANpJ%2BZaEiIFr

The first part of the string is correct but at the end it differs from the output of the Mcrypt encryption string.


Solution

  • Thanks to @Topaco I managed to make it work

    I added the OPENSSL_ZERO_PADDING option to disable the PKCS7 padding, then I created a function to manually pad my string with 0x00

    function zero_padding($text)
    {
        if (strlen($text) % 8)
            $text = str_pad($text,strlen($text) + 8 - strlen($text) % 8, "\0");
        
        return $text;
    }
    
    $key = "123456SO";
    $text = "name=louis&cp=75013";
    
    $encMcrypt = mcrypt_encrypt(MCRYPT_DES, $key, $text, MCRYPT_MODE_cbc, "\0\0\0\0\0\0\0\0");
    $encOpenssl = openssl_encrypt(zero_padding($text), "des-cbc", $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, "\0\0\0\0\0\0\0\0");
    
    $encMcrypt = urlencode(base64_encode($encMcrypt));
    $encOpenssl = urlencode(base64_encode($encOpenssl));
    
    echo "Mcrypt :" . $encMcrypt;
    echo "OpenSsl:" . $encOpenssl;
    

    Output:

    Mcrypt : f0tF0ERITdKiI2SxrttYAJBVNBtoGR%2BD
    OpenSsl: f0tF0ERITdKiI2SxrttYAJBVNBtoGR%2BD