Reputation: 3943
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
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