【发布时间】:2020-10-09 03:56:48
【问题描述】:
我正在使用 aes.js 加密纯文本并在 c# 中解密
JS中的加密代码
var aesKey = "87E67EF6-ECFB-4295-ACA3-B3F06BE489B1-87E67EF6-ECFB-4295-ACA3-B3F06BE489B1";
var encrypted = CryptoJS.AES.encrypt(JSON.stringify(emailParams), aesKey, {
keySize: 256,
padding: CryptoJS.pad.Pkcs7
});
var encAesKey = aesKey;
var encData = new Object();
encData.pId = 1234;
encData.encAesKey = encAesKey;
encData.encAesData = encrypted.toString();
我正在尝试解密 C# 中的加密字符串
byte[] data = Convert.FromBase64String(cipherText);
MemoryStream ms = new MemoryStream();
Rijndael alg = Rijndael.Create();
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(key, new byte[] { 0x43, 0x72, 0x6e, 0x6d, 0x54, 0x4d, 0x65, 0x94, 0x16, 0x32, 0x44, 0x84, 0x7e, 0x18, 0x64, 0x76, 0x6e, 0x63, 0x64, 0x7a, 0x5f, 0x84, 0x7f, 0x9a });
alg.KeySize = 256;
alg.Key = pdb.GetBytes(32);
alg.IV = pdb.GetBytes(16);
alg.Padding = PaddingMode.PKCS7;
CryptoStream cs = new CryptoStream(ms, alg.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(data, 0, data.Length);
//cs.Close();
string st = System.Text.Encoding.ASCII.GetString(ms.ToArray());
return st;
如果我取消注释 cs.Close(); 行,则会在此行抛出“填充无效且无法删除”。
如果我评论cs.Close(); 行,它正在解密为垃圾数据。
这是什么原因?我错过了什么吗? 你能帮我解决这个问题吗
【问题讨论】:
-
这两个代码根本不适合,因为使用了不同的 KDF。
Rfc2898DeriveBytes对应的 CryptoJS 是PBKDF2。 KDF 与随机生成的盐结合使用,盐与密文一起发送给接收者。 IV 要么通过 KDF 生成(与密钥一起),要么单独生成(在后一种情况下也是随机生成的,并与盐/密文一起发送)。 -
解决方案是什么?我需要解密加密的字符串。使用 CryptoJS.AES.encrypt 加密
-
当前 CryptoJS 代码使用 OpenSSL KDF
EVP_BytesToKey。如果不能更改 CryptoJS 代码,则需要一个 C# 对应项,例如here(未测试)。如果可以更改 CryptoJS 代码,那么 PBKDF2 将是一个更好的替代方案(更好,因为EVP_BytesToKey不是标准并且被认为相对不安全)。或者,可以直接使用密钥而不是密码。所以这取决于要求。 -
顺便说一下
encrypt.encrypt(aesKey)没有定义。请贴出相应的代码。 -
encrypt.encrypt(aesKey) 在这部分不需要。更新了问题