[英]How to convert CryptoJS decryption code into C#?
I have this code in CryptoJS, inside browser:我在浏览器内的 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;
};
This code is not written by me.这段代码不是我写的。 Also the cipherText
come from another server that I have no access to. cipherText
也来自我无法访问的另一台服务器。 However, I have access to key
and to iv
.但是,我可以访问key
和iv
。
I can decrypt that cipherText
inside a browser's console.我可以在浏览器的控制台中解密该cipherText
。 But I want to use these keys to decrypt that cipherText
inside C# code.但我想使用这些密钥来解密cipherText
代码中的密文。 Here's the code I've written:这是我写的代码:
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;
}
I have some problems though.不过我有一些问题。 I don't understand if I'm correctly decoding the given cipherText
from hexadecimal or not.我不明白我是否正确地从十六进制解码给定的cipherText
。 Also I can't instantiate Rfc2898DeriveBytes
, because I don't know what the second parameter (salt) should be.我也无法实例化Rfc2898DeriveBytes
,因为我不知道第二个参数(盐)应该是什么。
Also I don't know where should I use that iv
I've gotten from the CryptoJS code.另外,我不知道应该在哪里使用我从 CryptoJS 代码中获得的iv
。
Could you please help?能否请你帮忙?
So that both codes are compatible, the following changes of the C# code are necessary:为了使两个代码兼容,需要对 C# 代码进行以下更改:
Decrypt
method must be changed from void
to string
. Decrypt
方法的返回类型必须从void
更改为string
。FromHexString
. Key 和 IV 必须像FromHexString
的密文一样被解码为十六进制。Rfc2898DeriveBytes
implements PBKDF2 and must not be applied (since the JavaScript code does not use PBKDF2 either). Rfc2898DeriveBytes
实现PBKDF2且不得应用(因为 JavaScript 代码也不使用 PBKDF2)。Encoding.Unicode
(which corresponds to UTF16LE in .NET), but with Encoding.UTF8
.解密后的数据不能使用Encoding.Unicode
(对应于 .NET 中的 UTF16LE)进行解码,而是使用Encoding.UTF8
进行解码。The C# code can handle 24 bytes keys (to support 3TDEA ) and 16 bytes keys (to support the less secure 2TDEA ). C# 代码可以处理 24 字节密钥(以支持3TDEA )和 16 字节密钥(以支持不太安全的2TDEA )。 The posted CryptoJS code also handles these key sizes plus additionally 8 bytes keys (to support the least secure, DES compatible variant 1TDEA ).发布的 CryptoJS 代码还处理这些密钥大小以及额外的 8 字节密钥(以支持最不安全的 DES 兼容变体1TDEA )。
The following C# code decrypts a ciphertext generated with CryptoJS and 3TDEA :以下 C# 代码解密使用 CryptoJS 和3TDEA生成的密文:
public string Decrypt()
{
byte[] key = FromHexString("000102030405060708090a0b0c0d0e0f1011121314151617"); // 24 bytes (3TDEA)
byte[] iv = FromHexString("0001020304050607"); // 8 bytes
byte[] ciphertext = FromHexString("2116057c372e0e95dbe91fbfd148371b8e9974187b71e7c018de89c757280ad342d4191d29472040ee70d19015b025e1");
string plaintext = "";
using (TripleDES tdes = TripleDES.Create())
{
tdes.Key = key;
tdes.IV = iv;
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, tdes.CreateDecryptor(tdes.Key, tdes.IV), CryptoStreamMode.Write))
{
cs.Write(ciphertext, 0, ciphertext.Length);
}
plaintext = Encoding.UTF8.GetString(ms.ToArray());
}
}
return plaintext;
}
The decryption is also possible with the posted JavaScript code, which shows the functional equivalence of both codes.也可以使用发布的 JavaScript 代码进行解密,该代码显示了两种代码的功能等效性。
Note: Since AES is more performant than TripleDES, AES should be used if possible .注意:由于 AES 比 TripleDES 性能更高,因此应尽可能使用 AES。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.