【问题标题】:tripledes encryption not yielding same results in PHP and C#Tripledes 加密在 PHP 和 C# 中不会产生相同的结果
【发布时间】:2011-01-28 20:57:25
【问题描述】:

当我使用 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
        $key = "ShHhd8a08JhJiho98ayslcjh";
        $input = "Let us meet at 9 o'clock at the secret place.";

        $td = mcrypt_module_open('tripledes', '', 'ecb', '');
        $iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
        mcrypt_generic_init($td, $key, $iv);
        $encrypted_data = mcrypt_generic($td, $input);
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);

        echo base64_encode($encrypted_data);
    ?>

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

【问题讨论】:

  • 每个的结果是否一致?至少对于哈希,我相信它们会生成随机盐。

标签: c# php encryption


【解决方案1】:

附带说明:如果您使用的是 ECB,则不需要 IV。实际上,使用 ECB 在大多数情况下是一种安全隐患,因此您确实需要使用其他东西,例如CBC,它使用 IV。 IV 是一个随机的、非秘密的值,其大小与密码块大小相同(3DES 为 8 字节)。必须为每条消息创建一个新的 IV,并且解密方必须知道加密方使用的 IV。在实践中,IV 与加密消息一起发送。

【讨论】:

    【解决方案2】:

    彼得是对的。 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;
    

    并让它工作(尽管安全性稍差)。

    【讨论】:

      【解决方案3】:

      我不懂 PHP,也没有仔细分析过你的 C# 代码,但是由于大多数加密字符串是相同的,也许数据的填充是不同的?也许 PHP 使用了不同于 C# 代码中使用的PaddingMode.PKCS7 的其他模式? (如果我可以发表评论,这将是一个评论......)

      【讨论】:

        猜你喜欢
        • 2014-07-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-23
        • 1970-01-01
        • 2015-07-12
        • 1970-01-01
        相关资源
        最近更新 更多