[转]AES.js加密解密与C#的相互转换(及MD5值计算)
[转]AES.js加密解密与C#的相互转换
原文链接:AES.js加密解密与C#的相互转换
注:删除了原文最后部分的调试截图,增加了扩展部分的内容(自己使用过程中遇到的问题)。
AES简介#
AES, Advanced Encryption Standard,其实是一套标准:FIPS 197,而我们所说的AES算法其实是Rijndael算法。
NIST (National INstitute of Standards and Technology) 在1997年9月12日公开征集更高效更安全的替代DES加密算法,第一轮共有15种算法入选,其中5种算法入围了决赛,分别是MARS,RC6,Rijndael,Serpent和Twofish。又经过3年的验证、评测及公众讨论之后Rijndael算法最终入选。
具体实现#
1.服务端加密/解密#
public class DecryptStringAES
{
/// <summary>
/// AES加密算法
/// </summary>
/// <param name="input">明文字符串</param>
/// <returns>字符串</returns>
public static string EncryptByAES(string input)
{
if (string.IsNullOrWhiteSpace(input))
{
return input;
}
using (RijndaelManaged rijndaelManaged = new RijndaelManaged())
{
rijndaelManaged.Mode = CipherMode.CBC;
rijndaelManaged.Padding = PaddingMode.PKCS7;
rijndaelManaged.FeedbackSize = 128;
rijndaelManaged.Key = Encoding.UTF8.GetBytes(Decrypt.Key);
rijndaelManaged.IV = Encoding.UTF8.GetBytes(Decrypt.AES_IV);
ICryptoTransform encryptor = rijndaelManaged.CreateEncryptor(rijndaelManaged.Key, rijndaelManaged.IV);
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(input);
}
byte[] bytes = msEncrypt.ToArray();
return Convert.ToBase64String(bytes);
}
}
}
}
/// <summary>
/// AES解密
/// </summary>
/// <param name="input">密文字节数组</param>
/// <returns>返回解密后的字符串</returns>
public static string DecryptByAES(string input)
{
if (string.IsNullOrWhiteSpace(input))
{
return input;
}
var buffer = Convert.FromBase64String(input);
using (RijndaelManaged rijndaelManaged = new RijndaelManaged())
{
rijndaelManaged.Mode = CipherMode.CBC;
rijndaelManaged.Padding = PaddingMode.PKCS7;
rijndaelManaged.FeedbackSize = 128;
rijndaelManaged.Key = Encoding.UTF8.GetBytes(Decrypt.Key);
rijndaelManaged.IV = Encoding.UTF8.GetBytes(Decrypt.AES_IV);
ICryptoTransform decryptor = rijndaelManaged.CreateDecryptor(rijndaelManaged.Key, rijndaelManaged.IV);
using (MemoryStream msEncrypt = new MemoryStream(buffer))
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srEncrypt = new StreamReader(csEncrypt))
{
return srEncrypt.ReadToEnd();
}
}
}
}
}
}
2.客户端(JS)#
定义Key/IV:
const key = CryptoJS.enc.Utf8.parse("1234567890000000");
const iv = CryptoJS.enc.Utf8.parse("1234567890000000");
加密方法:
//**************************************************************
//*字符串/对象加密
//* 0:需要解密的字符串或对象
//****************************************************************/
function Encrypt(o) {
if (typeof (o) === "string") {
if (o) {
var srcs = CryptoJS.enc.Utf8.parse(o);
return CryptoJS.AES.encrypt(srcs, key, {
keySize: 128 / 8,
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}).toString();
}
}
else if (typeof (o) === "object") {
for (var _o in o) {
if (o[_o]) {
var srcs = CryptoJS.enc.Utf8.parse(o[_o]);
o[_o] = CryptoJS.AES.encrypt(srcs, key, {
keySize: 128 / 8,
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}).toString();
}
};
}
return o;
}
解密方法:
//**************************************************************
//*字符串解密
//* str:需要解密的字符串
//****************************************************************/
function Decrypt(str) {
var decrypt = CryptoJS.AES.decrypt(str, key, {
keySize: 128 / 8,
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
var decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
return decryptedStr;
}
注:客户端和服务端的KEY/IV必须保持一致。
扩展部分#
1.前端计算MD5值#
在普通 html 页面直接引入 cdn 的方式来引入 crypto-js:
<script src="https://cdn.bootcdn.net/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
以下是使用CryptoJS.MD5生成字符串的MD5值,并将其转换成小写字符串、大写字符串和base64编码的示例:
- 将MD5值转换成小写字符串:
var hash = CryptoJS.MD5('hello');
console.log(hash.toString(CryptoJS.enc.Hex)); // 输出:5d41402abc4b2a76b9719d911017c592
console.log(hash.toString(CryptoJS.enc.Latin1)); // 输出:]A@\¬K*h¹qÚ|Y
console.log(hash.toString(CryptoJS.enc.Utf8)); // 输出:]A@\¬K*h¹qÚ|Y
console.log(hash.toString(CryptoJS.enc.Base64)); // 输出:XUFBArxLK2y5ccmRGAF8Wg==
console.log(hash.toString()); // 输出:5d41402abc4b2a76b9719d911017c592
- 将MD5值转换成大写字符串:
var hash = CryptoJS.MD5('hello');
console.log(hash.toString(CryptoJS.enc.Hex).toUpperCase()); // 输出:5D41402ABC4B2A76B9719D911017C592
console.log(hash.toString(CryptoJS.enc.Latin1).toUpperCase()); // 输出:]A@\¬K*H¹QÚ|Y
console.log(hash.toString(CryptoJS.enc.Utf8).toUpperCase()); // 输出:]A@\¬K*H¹QÚ|Y
console.log(hash.toString(CryptoJS.enc.Base64).toUpperCase()); // 输出:XUFBARXLK2Y5CCMRGAF8WQ==
console.log(hash.toString().toUpperCase()); // 输出:5D41402ABC4B2A76B9719D911017C592
- 将MD5值转换成base64编码:
var hash = CryptoJS.MD5('hello');
console.log(hash.toString(CryptoJS.enc.Base64)); // 输出:XUFBArxLK2y5ccmRGAF8Wg==
2.CryptoJS默认编码格式#
CryptoJS默认使用UTF-8编码格式处理字符串,在使用MD5算法加密字符串时,可以直接传入原始字符串,CryptoJS会自动将其转换成UTF-8编码的字节数组。
如果需要使用其他编码格式,可以在调用加密函数之前,手动将字符串转换成指定编码的字节数组,然后再传入加密函数进行处理。例如,将字符串转换成Latin1编码的字节数组:
var str = 'hello';
var latin1 = CryptoJS.enc.Latin1.parse(str);
var hash = CryptoJS.MD5(latin1);
console.log(hash.toString()); // 输出:13d2eaa6f3d80ca58f37c2597efec15f
注:在使用不同编码格式时,输出结果可能会不同,需要根据具体场景选择合适的编码方式。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
2020-06-13 C#使用Stateless和箭头控件实现状态机的控制及显示