我有一个使用 DES 加密的 C# 加密方法。我需要在我正在创建的 node.js api 中解密该值。我已经设法在 api 中重新创建了大部分解密方法,但是当我传入秘密和要解密的值时,我得到了不同的结果。
加密.cs
public static string Encrypt(string toEncrypt, string key)
{
var des = new DESCryptoServiceProvider();
var ms = new MemoryStream();
des.Key = HashKey(key, des.KeySize / 8);
des.IV = HashKey(key, des.KeySize / 8);
string s = Encoding.UTF8.GetString (des.Key);
des.IV = Encoding.UTF8.GetBytes (key);
byte[] inputBytes = Encoding.UTF8.GetBytes(toEncrypt);
var cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(inputBytes, 0, inputBytes.Length);
cs.FlushFinalBlock();
return HttpServerUtility.UrlTokenEncode(ms.ToArray());
}
public static string Decrypt(string toDecrypt, string key)
{
var des = new DESCryptoServiceProvider();
var ms = new MemoryStream();
des.Key = HashKey(key, des.KeySize / 8);
des.IV = HashKey(key, des.KeySize / 8);
byte[] inputBytes = HttpServerUtility.UrlTokenDecode(toDecrypt);
var cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(inputBytes, 0, inputBytes.Length);
cs.FlushFinalBlock();
var encoding = Encoding.UTF8;
return encoding.GetString(ms.ToArray());
}
public static byte[] HashKey(string key, int length)
{
var sha = new SHA1CryptoServiceProvider();
byte[] keyBytes = Encoding.UTF8.GetBytes(key);
byte[] hash = sha.ComputeHash(keyBytes);
byte[] truncateHash = new byte[length];
Array.Copy(hash, 0, truncateHash, 0, length);
return truncateHash;
}
这是我继承的代码,到目前为止,我已经设法重新创建:
应用程序.js
var keyHex = 'Secret'
var ciphertext = 'EncryptedValue'
// Decrypt
var keyBytes = CryptoJS.enc.Utf8.parse(keyHex)
var sh1KeyVal = CryptoJS.SHA1(keyBytes)
var trunc = convertWordArrayToUint8Array(sh1KeyVal).slice(0, 8)
var decoded = decodeURI(ciphertext)
var key = trunc.toString(CryptoJS.enc.Utf8)
var bytes = CryptoJS.DES.decrypt(decoded, key, { iv: key });
var originalText = bytes.toString(CryptoJS.enc.Utf8);
console.log('Message: ', originalText);
秘密的散列过程是我能够重新创建的,并且我已经确认 api 中的值与方法输出trunc
的字节数组相同。HashKey
但是,当我使用var bytes = CryptoJS.DES.decrypt(decoded, key, { iv: key });
它进行简单加密时,会给出与 C# 方法不同的加密值,我认为这就是解密失败的原因。
我发现了一些东西,但我不确定如何解决是,当我传递密钥的值和要解密的值时,它们需要是字符串,但是在 C# 版本中,CryptoStream 需要一个字节数组,所以我必须做是将要解密的值作为字符串传递,我不确定这是否有效。密钥也是如此,DESCryptoServiceProvider
接受密钥和 iv 作为字节数组,但是当我转换 crypto-js 截断数组时,它只是转换字节数组的文字文本。我目前正在尝试使用以下方法进行转换:
var key = trunc.toString(CryptoJS.enc.Utf8)
我错过了这个过程中的一个步骤,我错过了什么吗?