如何将CryptoJS解密代码转换为C#?

问题描述 投票:1回答:1

我在浏览器内部的CryptoJS中有此代码:

var decrypt = function (cipherText) {
    var key = "a_long_key_goes_here";
    var iv = "initial_vector_goes_here";

    key = CryptoJS.enc.Hex.parse(key);
    iv = CryptoJS.enc.Hex.parse(iv);

    var decrypted = CryptoJS.TripleDES.decrypt({
        ciphertext: CryptoJS.enc.Hex.parse(cipherText)
    }, key, {
        iv: iv,
        mode: CryptoJS.mode.CBC
    });
    var clearText = decrypted.toString(CryptoJS.enc.Utf8);
    return clearText;
};

此代码不是我编写的。另外,cipherText来自我无法访问的另一台服务器。但是,我可以访问keyiv

我可以在浏览器的控制台中解密cipherText。但是我想使用这些密钥来解密C#代码中的cipherText。这是我编写的代码:

public void Desrypt()
{
    ICryptoTransform decryptor;
    UTF8Encoding encoder;
    string key = "a_long_key_goes_here";
    string iv = "initial_vector_goes_here";
    var cipherText = "cipher_text_goes_here";
    string clearText = "";

    byte[] cipherBytes = FromHexString(cipherText);
    using (Aes aes = Aes.Create())
    {
        Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(key, new byte[] { });
        aes.Key = pdb.GetBytes(32);
        aes.IV = pdb.GetBytes(16);
        using (MemoryStream ms = new MemoryStream())
        {
            using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write))
            {
                cs.Write(cipherBytes, 0, cipherBytes.Length);
                cs.Close();
            }
            clearText = Encoding.Unicode.GetString(ms.ToArray());
        }
    }
    return clearText;
}

public static byte[] FromHexString(string hexString)
{
    var bytes = new byte[hexString.Length / 2];
    for (var i = 0; i < bytes.Length; i++)
    {
        bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
    }
    return bytes;
}

不过我有一些问题。我不知道我是否从十六进制正确解码给定的cipherText。我也无法实例化Rfc2898DeriveBytes,因为我不知道第二个参数(盐)应该是什么。

而且我也不知道我应该在哪里使用从CryptoJS代码获得的iv

您能帮忙吗?

c# cryptography cryptojs
1个回答
2
投票

为了使两个代码兼容,必须对C#代码进行以下更改:

  • Decrypt方法的返回类型必须从void更改为string
  • 密钥和IV必须像使用FromHexString的密文一样以十六进制进行解码。
  • 必须使用TripleDES代替AES。
  • [Rfc2898DeriveBytes实现Rfc2898DeriveBytes,并且不得应用(因为JavaScript代码也不使用PBKDF2)。
  • 解密后的数据不得使用PBKDF2(与.NET中的UTF16LE对应,而应使用Encoding.Unicode进行解码。

C#代码可以处理24个字节的密钥(以支持Encoding.Unicode)和16个字节的密钥(以支持不太安全的Encoding.UTF8)。发布的CryptoJS代码还处理这些密钥大小以及另外8个字节的密钥(以支持最不安全的DES兼容变体Encoding.UTF8)。

以下C#代码解密使用CryptoJS和3TDEA生成的密文:

3TDEA

发布的JavaScript代码也可以解密,该代码显示了两个代码的功能等效。

注意:由于AES比TripleDES性能更高,因此应使用AES 如果可能

© www.soinside.com 2019 - 2024. All rights reserved.