Piero Alberto
Piero Alberto

Reputation: 3943

C# and PHP encryption compatibility - 3DES ECB with PKCS7

I have a common problem but none of the various solutions in the web seems working for me.

I have C# code which make an encrypt 3DES-ECB with PKCS7. I have to do the same in PHP, but I'm getting different results.

This is my C# code:

        public string Encrypt(string toEncrypt, string key)
    {
        byte[] keyArray;
        byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
        System.Configuration.AppSettingsReader settingsReader = new AppSettingsReader();
            MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
            keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
            //Always release the resources and flush data
            // of the Cryptographic service provide. Best Practice
            hashmd5.Clear();            
        TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();

        tdes.Key = keyArray;
        tdes.Mode = CipherMode.ECB;
        tdes.Padding = PaddingMode.PKCS7;
        ICryptoTransform cTransform = tdes.CreateEncryptor();
        byte[] resultArray =
          cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
        tdes.Clear();
        return Convert.ToBase64String(resultArray, 0, resultArray.Length);
    }

I've made a lot of tries in php... this is only one of them:

function apiEncode($data)
{    
  $key = "6702BC24DD0527E7";

  //Pad for PKCS7
  $blockSize = mcrypt_get_block_size('tripledes', 'ecb');
  $len = strlen($data);
  $pad = $blockSize - ($len % $blockSize);
  $data .= str_repeat(chr($pad), $pad);

  //Encrypt data
  $encData = mcrypt_encrypt('tripledes', $key, $data, 'ecb');
  return base64_encode($encData);
}

I'm using a random key, you can find it in the php sample code.

When the input is "00010", the C# code returns "FcXBCikZU64=" while the php gives to me "FIg+xqod9iY=".

Why? I think I'm doing all the stuff I've found in the blogs/tutorials/etc... so, what's the problem in my case?

UPDATE:

I have add, but still bad news...

$key .= substr($key,0,8);

function apiEncode($data)
{    
  $key = "6702BC24DD0527E7";

  //Pad for PKCS7
  $blockSize = mcrypt_get_block_size('tripledes', 'ecb');
  $len = strlen($data);
  $pad = $blockSize - ($len % $blockSize);
  $data .= str_repeat(chr($pad), $pad);

  $key .= substr($key,0,8); // append the first 8 bytes onto the end

  //Encrypt data
  $encData = mcrypt_encrypt('tripledes', $key, $data, 'ecb'); //, $iv);
  return base64_encode($encData);
}

now the output is hbJpiCNmXz8=... still not what I need..

UPDATE2: the problem is that, on c# side, I make an hash and I don't know how to do it in php.. look the code "tabbed", is where I do the hash in c# side.. how can I do it in php one?

SOLUTION:

function apiEncode($data)
{    
  //Pad for PKCS7
  $blockSize = mcrypt_get_block_size('tripledes', 'ecb');
  $len = strlen($data);
  $pad = $blockSize - ($len % $blockSize);
  $data .= str_repeat(chr($pad), $pad);

  $key = "6702BC24DD0527E7";
  $key = md5($key,TRUE);
  $key .= substr($key,0,8);
  //Encrypt data
  $encData = mcrypt_encrypt('tripledes', $key, $data, 'ecb');
  return base64_encode($encData);
}

 $crypt = apiEncode("00010");     
    echo "CRYPT: $crypt";

Upvotes: 2

Views: 1641

Answers (1)

xanatos
xanatos

Reputation: 111810

PHP code:

$key = "6702BC24DD0527E7";
$key = md5($key,TRUE);
$key .= substr($key,0,8);

The C# code is "ok" as it is.

"ok" is a big word here. I would probably use SHA256 and trim it to 24 bytes:

C#:

SHA256Managed sha256 = new SHA256Managed();
keyArray = sha256.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
Array.Resize(ref keyArray, 24);
//Always release the resources and flush data
// of the Cryptographic service provide. Best Practice
sha256.Clear(); 

and PHP:

$key = "6702BC24DD0527E7";
$key = hash("sha256",$key,TRUE);
$key = substr($key,0,24);

and still would be "lower case OK"... Normally you should use AES and one of the various block chaining modes, like CBC (that requires a IV), and the password should be "strenghtened" with an algorithm, like PBKDF2 (requires PHP >= 5.5)

Upvotes: 2

Related Questions