mat*_*anm 6 php c# cryptography mcrypt
我继承了一些C#代码,需要将它移植到PHP.这里是:
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));
Run Code Online (Sandbox Code Playgroud)
我的PHP代码如下所示:
$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);
Run Code Online (Sandbox Code Playgroud)
但是这两个解密的值并不相同,我无法弄清楚原因.我在这里和其他地方已经阅读了很多类似的问题,但它们似乎都没有解释我遇到的问题.
我真的很感激帮助找出解密的PHP字符串与解密的C#字符串不匹配的原因.
我终于在PHP 手册的 Mcrypt 页面的评论中找到了答案:
在 PHP 和 C# 之间使用 3DES 时,需要注意的是,存在细微的差异,如果不严格遵守,将导致恼人的数据加密/解密问题。
1)、当使用 16 字节密钥时,php 和 c# 生成完全不同的结果字符串。php 和 c# 似乎需要 24 字节密钥才能正常工作。
2),php没有“padding”选项,而c#有3个(?)。我的解决方法是在源字符串末尾添加空值,即 chr(0),使其大小为 8 倍,而在 c# 中,需要 PaddingMode.Zeros。
3) 在 php 中,密钥大小必须是 8 的倍,才能适用于 c#。
这里的关键点是#1。由于使用的密钥是 md5 散列的结果,因此它将是 16 个字节。如果我使用 24 字节密钥来加密(然后解密)一切都很好。
到目前为止,我还无法找到为什么16 字节密钥会产生不同结果的解释(或者是否有解决方法)。如果您有任何相关信息,请分享!