How do my C # and PHP decryption methods differ?

I have inherited some C # code and I need to port it to PHP. Here he is:

string key = "some key"; string strEncrypted = "some encrypted string"; byte[] hashedKey = new MD5CryptoServiceProvider().ComputeHash(UTF8Encoding.UTF8.GetBytes(key)); byte[] strToDecrypt = Convert.FromBase64String(strEncrypted); TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider(); tripleDES.Key = hashedKey; tripleDES.Mode = CipherMode.ECB; string strDecrypted = UTF8Encoding.UTF8.GetString(tripleDES.CreateDecryptor().TransformFinalBlock(strToDecrypt, 0, strToDecrypt.Length)); 

My PHP code looks like this:

 $key = 'some key'; $str_encrypted = 'some encrypted string'; $hashed_key = md5($key, TRUE); $str_to_decrypt = base64_decode($str_encrypted); // The IV isn't used for ECB, but it prevents a warning. $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_TRIPLEDES, MCRYPT_MODE_ECB), MCRYPT_RAND); $str_decrypted = mcrypt_decrypt(MCRYPT_TRIPLEDES, $hashed_key, $str_to_decrypt, MCRYPT_MODE_ECB, $iv); 

But the two decrypted values ​​do not match, and I cannot understand why. I read a lot of similar questions here and elsewhere, but none of them seem to explain what I have.

I would really appreciate any help in figuring out why the PHP decrypted string does not match the C # decrypted string.

+6
c # php cryptography mcrypt
source share
3 answers

I finally managed to find the answer in the comment on the Mcrypt page of the PHP manual :

When using 3DES between PHP and C #, it should be noted that there are subtle differences that, if not strictly followed, will lead to the annoying problem of data encryption / decryption.

one). When using a key with 16 bytes, php and C # generate a common result string. it seems that php and c # require 24 bytes to work.

2), php has no "fill" option, and C # has 3 (?). My job is to add zeros, i.e. chr (0), to the end of the original line to make my size 8 times, whereas in C # PaddingMode.Zeros is required.

3) the key size must be 8 times, in php, so that it works in C #.

The key point here is # 1. Since the key used is the result of md5 hashing, it will be 16 bytes. If instead I use a 24-byte key for encryption (and then decryption), then all this is hunky-dory.

So far, I have not been able to find explanations why 16-byte keys produce a different result (or is there a workaround). If you have information about this, please share!

+2
source share

You can view this forum: http://forums.asp.net/t/1498290.aspx Apparently, last year someone had the same problem.

From this site, it looks like C # stuff should be encoded in UTF-7 .. Not UTF-8.

+2
source share

C # key encoded in UTF8 before MD5 hashed. Perhaps the equivalent of PHP is not?

C # output is also again encoded by UTF8.

I'm not very familiar with PHP, but apparently you need the utf8_encode function, so try updating your side of PHP:

 $key = 'some key'; $str_encrypted = 'some encrypted string'; $hashed_key = md5(utf8_encode($key), TRUE); $str_to_decrypt = base64_decode($str_encrypted); // The IV isn't used for ECB, but it prevents a warning. $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_TRIPLEDES, MCRYPT_MODE_ECB), MCRYPT_RAND); $str_decrypted = utf8_encode(mcrypt_decrypt(MCRYPT_TRIPLEDES, $hashed_key, $str_to_decrypt, MCRYPT_MODE_ECB, $iv)) 

Besides the difference in UTF8 encoding, it is not guaranteed (from the samples you provided) that str_encrypted is base64 encoded, on the C # or php side.

It is best to take colit tips and repeat the input so that all the input matches at the byte level.

0
source share

All Articles