ECB解密问题中的c#三重DES


C# Triple DES in ECB Decrypt Issues

我有这个PHP脚本,我们需要转换为c#来解码来自API post请求的结果,但我遇到了c#实现的问题。

我们在运行PHP脚本XXXX-XXXX-XXXX时得到了很好的结果,但是得到了不同的错误。

的值是:

encodedText = "U8Q+m2zpFMLa/3gYILHx5w=="
key = "examplesecret"
keyHash = "6315046b2c085bbeeab87c65"
Php脚本:

<?php
$secret = 'examplesecret';
$encrypted_code = 'U8Q+m2zpFMLa/3gYILHx5w==';
// Base64
// Decode
$encrypted_code = base64_decode( $encrypted_code );
// Create decryption module
$cipher = mcrypt_module_open( 'tripledes', '', 'ecb', '' );
$keysize = mcrypt_enc_get_key_size( $cipher ); // = 24
// Generate key
$hash = md5( $secret );
$key = substr( $hash, 0, $keysize );
// Initialise decrypter
$iv = mcrypt_create_iv( mcrypt_enc_get_iv_size( $cipher ),
MCRYPT_DEV_RANDOM );
mcrypt_generic_init( $cipher, $key, $iv );
// Decrypt code
$decrypted = mdecrypt_generic( $cipher, $encrypted_code );
// Output decrypted code
echo $decrypted;
?>
c#脚本

public static string Decrypt(string encodedText, string key)
{
    TripleDESCryptoServiceProvider desCryptoProvider = new TripleDESCryptoServiceProvider();
    MD5CryptoServiceProvider hashMD5Provider = new MD5CryptoServiceProvider();
    byte[] byteHash;
    byte[] byteBuff;
    byteHash = hashMD5Provider.ComputeHash(Encoding.UTF8.GetBytes(key));
    desCryptoProvider.Key = byteHash;
    desCryptoProvider.Padding = PaddingMode.None;
    desCryptoProvider.Mode = CipherMode.ECB; //CBC, CFB
    byteBuff = Convert.FromBase64String(encodedText);
    var byteHex = BitConverter.ToString(byteBuff).Replace("-", " ");
    string plaintext = Encoding.UTF8.GetString(desCryptoProvider.CreateDecryptor().TransformFinalBlock(byteHex, 0, byteHex.Length));
    return plaintext;
}

我看到了以下几点:

  1. 在PHP中通过substr派生$key;但只是以c#中的MD5输出为例,它们是相同的吗?(例如,如果PHP的值是一个十六进制字符串,那么16字节的MD5是32个字符,它被截断为24个字符,是一个12字节(96位)的值;在c#中是16字节)
  2. 说到密钥,如果你使用5.6之前的PHP,一个有缺陷的密钥是0填充的(根据mcrypt_encrypt;c#不会为你做这些。这是另一件需要检查的事情。
  3. 你在PHP代码中有一个IV,但ECB不使用IV。这不会导致你的问题,但它不太理想。
  4. 当然,我应该在这一点上警告欧洲央行"太稳定",不会隐藏加密数据中的模式,也不会隐藏你再次发送相同消息的情况。
  5. TransformFinalBlock需要字节,但你似乎在这里给它一个字符串。因为c#是一种强类型语言,所以这不是你正在运行的代码。
  6. 你应该避免谈论算法的具体实现。TripleDES.Create()优于new TripleDESCryptoServiceProvider(), MD5.Create()优于new MD5CryptoServiceProvider();并将变量输入为TripleDES和MD5。
  7. TripleDES对象、MD5对象和CreateDecryptor()的输出都是IDisposable的,所以你应该把它们包装在using语句中,以更有效地利用你的本地资源。

最可能的问题是,您没有在两种语言中生成相同的键。