0

I need to pass a 3DES encrypted string to a php web page from c# and i'm having no luck.

In short the PHP code I am trying to convert is :

    $message = $request->get('searchHash');
    $searchHash = base64_decode(rawurldecode($message));
    $key = $this->container->getParameter("api_encryption_key");
    $decrypted = mcrypt_decrypt(MCRYPT_3DES, $key, $searchHash, MCRYPT_MODE_ECB);
    //$data = unserialize($decrypted);
    $searchString = str_replace("\x0", '', $decrypted);

which I have re-wriiten as:

        using (TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider())
        {
            byte[] iv0 = { 0, 0, 0, 0, 0, 0, 0, 0 };
            byte[] toEncryptArray = Encoding.ASCII.GetBytes(toEncrypt);

            tdes.IV = iv0;
            tdes.Key = Encoding.ASCII.GetBytes(key);
            tdes.Mode = CipherMode.ECB;
            tdes.Padding = PaddingMode.Zeros;

            ICryptoTransform cTransform = tdes.CreateEncryptor();

            byte[] resultArray =
                cTransform.TransformFinalBlock(toEncryptArray, 0,
                    toEncryptArray.Length);

            tdes.Clear();

            return resultArray.ToString();
        }

however the results from c# are not consistent with those of php.

Can anyone shed any light as to why?

Thanks.

Anthony Walters
  • 143
  • 1
  • 12
  • The function mcrypt_decrypt is deprecated. You should replace mcrypt_encrypt with openssl_decrypt. – odan Aug 06 '17 at 21:07
  • Thanks but that isn't an option in this case as it is a 3rd party system – Anthony Walters Aug 06 '17 at 21:09
  • We have seen a bunch of 3DES ECB question suddenly, it this a homework question? – zaph Aug 06 '17 at 22:38
  • It is best not to use mcrypt, it is abandonware, has not been updated in years and does not support standard PKCS#7 (née PKCS#5) padding, only non-standard null padding that can't even be used with binary data. mcrypt has many outstanding [bugs](https://sourceforge.net/p/mcrypt/bugs/) dating back to 2003. The mcrypt-extension is deprecated will be removed in PHP 7.2. Instead consider using [defuse](https://github.com/defuse/php-encryption) or [RNCryptor](https://github.com/RNCryptor), they provide a complete solution and are being maintained and is correct. – zaph Aug 06 '17 at 22:38
  • What is a typical key? 3DES requires a 24-byte key. Provide example test input and output, binary data in hex, that probably includes incorrectly decrypted data for both the PHP and C# implementations. IOW a [mcve]. – zaph Aug 06 '17 at 22:40

1 Answers1

0

You need to return Convert.ToBase64String(resultArray) in the C# code. Returning resultArray.ToString() will give you System.Byte[] and not what you're expecting. The PHP code will then fail.

C#:

string toEncrypt = "SecretText";
string key = "SecretKeySecretKeySecret";

using (TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider())
{
    byte[] iv0 = { 0, 0, 0, 0, 0, 0, 0, 0 };
    byte[] toEncryptArray = Encoding.ASCII.GetBytes(toEncrypt);

    tdes.IV = iv0;
    tdes.Key = Encoding.ASCII.GetBytes(key);
    tdes.Mode = CipherMode.ECB;
    tdes.Padding = PaddingMode.Zeros;

    ICryptoTransform cTransform = tdes.CreateEncryptor();

    byte[] resultArray =
        cTransform.TransformFinalBlock(toEncryptArray, 0,
            toEncryptArray.Length);

    tdes.Clear();

    string s = Convert.ToBase64String(resultArray);
}

PHP:

<?php
$message = "b9ssRELdtRWVlNuJqaYUrg==";
$searchHash = base64_decode(rawurldecode($message));
$key = "SecretKeySecretKeySecret";
$decrypted = mcrypt_decrypt(MCRYPT_3DES, $key, $searchHash, MCRYPT_MODE_ECB);
//$data = unserialize($decrypted);
$searchString = str_replace("\x0", '', $decrypted);

echo $searchString;
UnholyRanger
  • 1,977
  • 14
  • 24