三重加密在PHP和C#中没有产生相同的结果

当我用C#加密时,我得到arTdPqWOg6VppOqUD6mGITjb24+x5vJjfAufNQ4DN7rVEtpDmhFnMeJGg4n5y1BN

 static void Main(string[] args) { Encoding byteEncoder = Encoding.Default; String key = "ShHhd8a08JhJiho98ayslcjh"; String message = "Let us meet at 9 o'clock at the secret place."; String encryption = Encrypt(message, key, false); String decryption = Decrypt(encryption , key, false); Console.WriteLine("Message: {0}", message); Console.WriteLine("Encryption: {0}", encryption); Console.WriteLine("Decryption: {0}", decryption); } public static string Encrypt(string toEncrypt, string key, bool useHashing) { byte[] keyArray; byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt); if (useHashing) { MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider(); keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key)); } else keyArray = UTF8Encoding.UTF8.GetBytes(key); 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); return Convert.ToBase64String(resultArray, 0, resultArray.Length); } public static string Decrypt(string toDecrypt, string key, bool useHashing) { byte[] keyArray; byte[] toEncryptArray = Convert.FromBase64String(toDecrypt); if (useHashing) { MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider(); keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key)); } else keyArray = UTF8Encoding.UTF8.GetBytes(key); TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider(); tdes.Key = keyArray; tdes.Mode = CipherMode.ECB; tdes.Padding = PaddingMode.PKCS7; ICryptoTransform cTransform = tdes.CreateDecryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); return UTF8Encoding.UTF8.GetString(resultArray); } 

当我使用PHP加密时,我得到: arTdPqWOg6VppOqUD6mGITjb24+x5vJjfAufNQ4DN7rVEtpDmhFnMVM+W/WFlksR

   

我对密码学知之甚少,无法弄清楚原因。 有任何想法吗? 谢谢。

彼得是对的。 PHP只是用零填充,而你在C#代码中使用PKCS#7。 这是一些应该正确的代码:

 function pkcs7_pad($text, $blocksize) { $pad = $blocksize - (strlen($text) % $blocksize); return $text . str_repeat(chr($pad), $pad); } $input = pkcs7_pad("Let us meet at 9 o'clock at the secret place.", 16); 

或者,您应该能够将它放在C#代码中:

 tdes.Padding = PaddingMode.Zeros; 

并且它也有效(虽然稍微不那么安全)。

我不知道PHP,也没有仔细分析你的C#代码,但由于大多数加密字符串是相同的,数据的填充可能是不同的? 也许PHP使用的另一种模式不是C#代码中使用的PaddingMode.PKCS7 ? (如果我可以发表评论,这本来就是评论……)

作为旁注:如果您使用的是ECB,那么您不需要IV。 实际上,使用ECB大多数时候都存在安全隐患,因此您确实需要使用其他东西,例如使用IV的CBC。 IV是随机的非秘密值,其大小与密码块大小相同(3DES为8个字节)。 必须为每条消息创建一个新的IV,并且解密方必须知道加密方使用的IV。 实际上,IV与加密消息一起发送。