Javascript 改进TypeScript中CryptoJS的安全实现,使其与ASP.NET中的C#兼容
我已经在Angular 10中使用了通过node package manager安装的crypto js,ASP.NET MVC将从服务器端执行 用于来回加密和解密,以便从数据库生成任何DML语句 下面的代码片段给出了从TypeScript加密和从ASP.NET解密的完整操作 角度字体脚本(加密) ASP.NET MVC(解密)Javascript 改进TypeScript中CryptoJS的安全实现,使其与ASP.NET中的C#兼容,javascript,c#,asp.net,encryption,cryptojs,Javascript,C#,Asp.net,Encryption,Cryptojs,我已经在Angular 10中使用了通过node package manager安装的crypto js,ASP.NET MVC将从服务器端执行 用于来回加密和解密,以便从数据库生成任何DML语句 下面的代码片段给出了从TypeScript加密和从ASP.NET解密的完整操作 角度字体脚本(加密) ASP.NET MVC(解密) 上面显示的代码片段非常有效。但说到安全性,这里有几个需要处理和解决的问题 使用ECB模式在语义上是不安全的 键和IV源于盐,它是静态的 在使其完全安全地兼容于双
上面显示的代码片段非常有效。但说到安全性,这里有几个需要处理和解决的问题
- 使用ECB模式在语义上是不安全的
- 键和IV源于盐,它是静态的
在使其完全安全地兼容于双方之后,我们需要如何实现呢?您可以在两端使用NaClO——它支持现代密码,使用相同的库可以轻松确保兼容性,NaClO专门用于高级API(
crypto_secretbox
)中的易用性。
import * as CryptoJS from 'crypto-js';
public encrypt (model: any) {
try {
let plainModel = model.toString();
let encryptionKey = CryptoJS.enc.Utf8.parse('This is my Secret Key');
let salt = CryptoJS.enc.Base64.parse('SXZhbiBNZWR2ZWRldg=='); // this is the byte array
let iterations = 1000;
// https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.rfc2898derivebytes?view=netcore-3.1
let keyAndIv = CryptoJS.PBKDF2(encryptionKey, salt, {
keySize: 256 / 32 + 128 / 32,
iterations: iterations,
hasher: CryptoJS.algo.SHA1
});
// so PBKDF2 in CryptoJS is direct in that it
// always begins at the beginning of the password, whereas the .net
// implementation offsets by the last length each time .GetBytes() is called
// so we had to generate a Iv + Salt password and then split it
let hexKeyAndIv = CryptoJS.enc.Hex.stringify(keyAndIv);
let key = CryptoJS.enc.Hex.parse(hexKeyAndIv.substring(0, 64));
let iv = CryptoJS.enc.Hex.parse(hexKeyAndIv.substring(64, hexKeyAndIv.length));
// As you're using Encoding.Unicode in .net, we have to use CryptoJS.enc.Utf16LE here.
let encryptedStr = CryptoJS.AES.encrypt(CryptoJS.enc.Utf16LE.parse(plainModel), key, {iv: iv}).toString();
return encryptedStr;
} catch (ex) {
console.log(ex);
}
}
using System;
using System.Security.Cryptography;
using System.IO;
using System.Text;
private string Decrypt(string cipherText)
{
string EncryptionKey = "This is my Secret Key";
cipherText = cipherText.Replace(" ", "+");
byte[] cipherBytes = Convert.FromBase64String(cipherText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(cipherBytes, 0, cipherBytes.Length);
cs.Close();
}
cipherText = Encoding.Unicode.GetString(ms.ToArray());
}
}
return cipherText;
}
salt = CryptoJS.enc.Base64.parse('SXZhbiBNZWR2ZWRldg==');
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });