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

Converting C# Cryptography.Rijndael encryption to Javascript (pref. crypto-js)

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

密码目前使用 C# 的 Cryptography.Rijndael(N.B。不是 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();

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

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

byte[] key = Convert.FromBase64String(base64Key);
byte[] iv = Convert.FromBase64String(base64IV);

N.B。我无法控制 C# 代码(遗留系统)。

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

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

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

var keyCodeWords = CryptoJS.enc.Base64.parse(base64Key);
var ivCodeWords = CryptoJS.enc.Base64.parse(base64IV);

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

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

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

代码运行正常...您的问题可能出在 C# 或 Javascript 中 password/IV 的处理...在 C# 中:https://ideone.com/APC4MM and in Javascript: https://jsfiddle.net/jjwy5472/

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

byte[] key = new byte[] 
{ 
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
};

byte[] iv = new byte[] 
{ 
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
    0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
};

明文是

"Hello world! This is a wonderful day! àèéìòù"

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

aa429aa5c1c928b86d81b43ff3fb6cc46f24cc73957bc7c00829357bf441eb3be9cf8aef2ff6f819f9b95c69886b169b6959c4f7ece0620c6a28f849516adee9

但请注意,Javascript 中的 encrypted 变量是一个复杂的对象,包含具有各种版本的加密数据的各种属性。 encrypted.toString() returns加密数据的base64版本,encrypted.ciphertext是一个WordArray(相当于byte[]的CryptoJS),而encrypted.ciphertext.toString()是它的十六进制版本(相当于在 C# 中执行 BitConverter.ToString(encryptedData).Replace("-", "").ToLowerInvariant())。