【发布时间】:2016-07-11 19:42:55
【问题描述】:
我有两个系统共享一个用户数据库,所以认证需要相同。
密码当前使用 C# 的 Cryptography.Rijndael(注:not 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);
注意我无法控制 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
});
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 一致?
【问题讨论】:
-
Rijndael 在 C# 中有上百万个选项。哪个是你的?你能给我们看一下代码吗?您是否检查过编码是否合适?请记住,AES 只是 Rijndael 的一个子集。如果您在 C# 中使用 128 位以外的块大小,则不能使用 CryptoJS。
-
您永远不应该加密您的用户密码。您需要使用散列代替一些强大的散列,例如 PBKDF2、bcrypt、scrypt 和 Argon2。由于散列函数是单向函数,因此您将无法“解密”散列。为了验证您的用户,您可以再次通过哈希函数运行密码,以便与存储在数据库中的哈希值进行比较。查看更多:How to securely hash passwords?
-
@ArtjomB。 , 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 位,`iv' 是 128 位。块大小为 128。不幸的是,我无法控制 C# 实现(旧系统)——我也只会使用散列。 -
@ArtjomB.,很抱歉我编辑了我的问题。请检查一下。谢谢。
-
好的,看起来不错。所以一定是编码问题。您如何将密码字符串编码为双方的字节?您如何在 CryptoJS 中提供来自 C# 的密钥和 IV?能提供对应的代码吗?您如何比较结果?
标签: javascript c# cryptojs rijndael