我需要将 Rijndael 加密函数从 C# 转换为 Node.js。但即使使用相同的密钥、IV、模式和块大小,我也无法匹配结果。我做错了什么?
C# MRE:
using System.Security.Cryptography;
byte[] encrypted;
using (Rijndael rijAlg = Rijndael.Create())
{
rijAlg.Key = new byte[] { 63, 115, 38, 206, 45, 102, 229, 13,
161, 196, 250, 133, 149, 70, 153, 33,
218, 32, 135, 149, 150, 21, 143, 11,
210, 115, 185, 163, 24, 70, 145, 141 };
rijAlg.IV = new byte[] { 151, 121, 168, 83, 221, 99, 206, 230, 74, 190, 106, 212, 232, 117, 192, 37 };
ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write("1234");
}
encrypted = msEncrypt.ToArray();
}
}
Console.WriteLine(rijAlg.BlockSize); //128
Console.WriteLine(rijAlg.Mode); //CBC
Console.WriteLine(rijAlg.Padding); //PKCS7
Console.WriteLine(Convert.ToBase64String(encrypted)); //6d9SB6t9dktDJ+siSlFtOQ==
}
节点/Javascript MRE:
import Rijndael from "rijndael-js";
const key = Buffer.from([63, 115, 38, 206, 45, 102, 229, 13, 161, 196, 250, 133, 149, 70, 153, 33, 218, 32, 135, 149, 150, 21, 143, 11, 210, 115, 185, 163, 24, 70, 145, 141]);
const IV = Buffer.from([151, 121, 168, 83, 221, 99, 206, 230, 74, 190, 106, 212, 232, 117, 192, 37]);
const cipher = new Rijndael(key, "cbc");
const buffer = cipher.encrypt("1234", "128", IV);
console.log(Buffer.from(buffer).toString("base64")); //6ewzPyaxUgFX8IXW9iLJfw==
在C#中加密
"1234"
的结果是"6d9SB6t9dktDJ+siSlFtOQ=="
,而在Node中是"6ewzPyaxUgFX8IXW9iLJfw=="
由于每个环境处理加密的方式存在差异,这可能有点棘手,特别是在填充和块大小等方面。
在您的 C# 代码中,您使用块大小为 128 位的 Rijndael(如 rijAlg.BlockSize 输出所示),填充模式为 PKCS7。这是 Rijndael/AES 加密的相当标准。
但是,在 Node.js 代码中,当您使用 rijndael-js 并调用 cipher.encrypt 时,您将指定“256”作为块大小。这可能会导致不匹配。 Rijndael 支持各种块大小,但 AES(Rijndael 的子集)固定为 128 位的块大小。
因此,您可能需要检查以下几件事:
尝试调整这些参数,看看是否可以解决差异。加密对这些细节可能有点挑剔,所以这一切都是为了确保一切都完美排列。
希望这对您有帮助,祝您的项目好运!