欧洲央行解密问题中的C#Triple DES

时间:2016-08-12 10:29:03

标签: c# php encryption des ecb

我有这个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 个答案:

答案 0 :(得分:2)

我看到的一些事情:

  1. 您通过PHP中的substr派生$key;但是只需要在C#中获取MD5的输出,它们是否相同? (例如,如果PHP的值是一个十六进制字符串,那么MD5的16个字节是32个字符,它被转换为24个字符,是一个12字节(96位)的值;在C#中它是#s;&#39; s 16字节)
  2. 说到密钥,如果你在5.6之前使用PHP,那么一个不足的密钥是0填充的(根据mcrypt_encrypt的文档; C#不会为你这样做。所以&# #39;另一件需要检查的事情。
  3. 您在PHP代码中有IV,但ECB不使用IV。这不会导致你的问题,但它不太理想。
  4. 当然,我应该在这一点上警告欧洲央行“太稳定了”#34;并且不会隐藏加密数据中的模式,也不会隐藏您再次发送相同的邮件。
  5. TransformFinalBlock占用字节,但你似乎在这里给它一个字符串。由于C#是一种强类型语言,因此这不是您正在运行的代码。
  6. 你应该避免谈论算法的具体实现。 TripleDES.Create()优先于new TripleDESCryptoServiceProvider()MD5.Create()优先于new MD5CryptoServiceProvider();并将变量键入TripleDES和MD5。
  7. TripleDES对象,MD5对象和CreateDecryptor()的输出都是IDisposable,因此您应该将它们包装在using语句中,以便更有效地使用本机资源。
  8. 但问题最可能的罪魁祸首是,您并未在两种语言中生成相同的密钥。