将 C# Cryptography.Rijndael 加密转换为 Javascript(首选 crypto-js)

Kho*_*elo 1 javascript c# rijndael cryptojs

我有两个共享用户数据库的系统,因此身份验证需要相同。

密码当前使用 C# 加密Cryptography.Rijndael(注意不是RijndaelManaged)。使用自定义密钥和 iv(初始化向量)。(CBC模式和Pkcs7填充)

C#加密如下:

Rijndael alg = Rijndael.Create();
alg.Key = key;
alg.IV = IV;
CryptoStream cs = new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(clearData, 0, clearData.Length);
cs.Close();
byte[] encryptedData = ms.ToArray();
Run Code Online (Sandbox Code Playgroud)

key是 256 位(32 字节),iv(初始化向量)是 128 位(16 字节)。块大小为 128 位(16 字节)。

key 和 iv 是来自 base64 字符串的字节数组,通过:

byte[] key = Convert.FromBase64String(base64Key);
byte[] iv = Convert.FromBase64String(base64IV);
Run Code Online (Sandbox Code Playgroud)

注意:我无法控制 C# 代码(遗留系统)。

在基于 javascript 的系统上,我必须以完全相同的方式加密密码。我尝试使用节点crypto-js但无济于事。我的代码看起来像这样:

var encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(password), keyCodeWords, {
    iv: ivCodeWords,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
});
Run Code Online (Sandbox Code Playgroud)

keyCodeWords 和 ivCodeWords 是来自相同 base64 key 和 iv 的 CryptoJS 代码字,如下所示:

var keyCodeWords = CryptoJS.enc.Base64.parse(base64Key);
var ivCodeWords = CryptoJS.enc.Base64.parse(base64IV);
Run Code Online (Sandbox Code Playgroud)

加密确实有效(从某种意义上说,我可以加密然后解密以获得相同的值)。但是,问题是加密值 ( encrypted.ciphertext) 与 C# 的值不同,因此我无法进行身份验证。

比较是通过比较 Base64 加密的输出字符串来完成的。

如何使 crypto-js(或任何其他 javascript 加密库)与 C# Rijndael 一致?

xan*_*tos 6

代码工作正常...您的问题可能是在 C# 或 Javascript 中处理密码/IV...在 C# 中:https: //ideone.com/APC4MM和在 Javascript 中: https: //jsfiddle.net /jjwy5472/

\n\n

我在这两种情况下都使用了相同的密码:

\n\n
byte[] key = new byte[] \n{ \n    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,\n    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,\n    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,\n    0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,\n};\n\nbyte[] iv = new byte[] \n{ \n    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,\n    0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n

明文是

\n\n
"Hello world! This is a wonderful day! \xc3\xa0\xc3\xa8\xc3\xa9\xc3\xac\xc3\xb2\xc3\xb9"\n
Run Code Online (Sandbox Code Playgroud)\n\n

在这两种情况下,生成的加密文本都是

\n\n
aa429aa5c1c928b86d81b43ff3fb6cc46f24cc73957bc7c00829357bf441eb3be9cf8aef2ff6f819f9b95c69886b169b6959c4f7ece0620c6a28f849516adee9\n
Run Code Online (Sandbox Code Playgroud)\n\n

但请注意,encryptedJavascript 中的变量是一个复杂的对象,包含各种属性以及各种版本的加密数据。encrypted.toString()返回加密数据的 base64 版本,encrypted.ciphertext是 a WordArray(相当于 CryptoJS 的byte[]),encrypted.ciphertext.toString()是它的十六进制版本(相当于BitConverter.ToString(encryptedData).Replace("-", "").ToLowerInvariant()C# 中的操作)。

\n