700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > C# 利用AEC算法加密解密实现前台后台安全校验 附前端后台代码示例

C# 利用AEC算法加密解密实现前台后台安全校验 附前端后台代码示例

时间:2022-07-19 15:40:19

相关推荐

C# 利用AEC算法加密解密实现前台后台安全校验 附前端后台代码示例

最近再新入职公司查看前端登录用ajax请求,发现使用这个AES加密,提升了一定的安全性,也加强了对

对密钥等概念的理解,和体会,所以研究了下记录于此。

关于AES算法解释见/qq_28205153/article/details/55798628

第一部分:前台加密

可以在这个GitHub的/brix/crypto-js上下载该js,它可以单独引入所需要加密方式的js;

主要是方便模块化

还可以引入一个crypto-js.js 这个文件,它相当于引入了所有的加密方式,我使用的就是后者一次引入所有的加密文件,这个文件也不是很大,还可以接受。下载地址/crypto-js/3.1.9-1/crypto-js.min.js(右键另存为即可)

参考如下/lz/p/8046816.html

<%--<script src="CryptoJS/components/core.js"></script><script src="CryptoJS/components/cipher-core.js"></script><script src="CryptoJS/components/mode-ecb.js"></script><script src="CryptoJS/components/enc-base64.js"></script><script src="CryptoJS/components/aes.js"></script>--%><script src="CryptoJS/crypto-js.min.js"></script><%--<script src="CryptoJS/CrptoJS.js"></script>--%><script>var Crypto = {Encrypt: function (plaintText) {var rsEncrypt = CryptoJS.AES.encrypt(plaintText, this.GenKey(), {iv: this.GenIV(),mode: CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});return CryptoJS.enc.Base64.stringify(rsEncrypt.ciphertext);},GenKey: function () {return CryptoJS.enc.Utf8.parse('X9Q0uft9inKg5Q50ImqQXg9inKg5Q56W');},GenIV: function () {return CryptoJS.enc.Utf8.parse('1234567890000000');}};save();function save() {var auth = Crypto.Encrypt("我是要加密的内容,且转为base64码的字符串,解密记得先转为对应!");console.log(auth);//var formData = new FormData();//formData.append("pdsauth", auth); }</script>

相关用法解释见/article/145746.htm

采用自定义密钥,和初始化变量,加密明文得到密文转为base64码后,变成如下字符串,

第二部分:后台加密

/zh-cn/dotnet/api/system.security.cryptography.aescryptoserviceprovider?view=netframework-4.8

加密:

new一个服务器提供器,分别赋值四个常用字段,

通过key密钥,vi初始化值构造加密器

定义一个内存流,加上加密器,构造加密流,

将明文写入加密流

/zh-cn/dotnet/api/system.security.cryptography.aescryptoserviceprovider.createencryptor?view=netframework-4.8

解密

同样new一个服务提供器对象,分别赋值,里面key和vi要一致

通过key密钥,vi初始化值构造解密器

用密文字节数组构造一个内存流,加上解密器,构造解密流

将解密流读出

/zh-cn/dotnet/api/system.security.cryptography.aescryptoserviceprovider.createdecryptor?view=netframework-4.8#System_Security_Cryptography_AesCryptoServiceProvider_CreateDecryptor

系统提供加密解密方法,都是操作密文的字节数组,

可能我们平时需要变成字符串密文,这里加密后得到密文数组,

加密后的密文数组,转为为字符串方式,常用转为base64或是上面自定义的方式,转为16进制字符串

那么解密也需要对应方式,将字符串按照同样的方式,转化为数组,这个一定要保持一致,

相关代码如下:

using System;using System.Collections.Generic;using System.IO;using System.Security.Cryptography;using System.Text;namespace Util.SecutyUtil{public abstract class AESUtil{private const string DEFAULT_AES_KEY = "X9Q0uft9inKg5Q50ImqQXg9inKg5Q56W";//32位 private const string DEFAULT_AES_IV = "1234567890000000";//16位 /// <summary> /// AES加密算法 /// </summary> /// <param name="input">明文字符串</param> /// <param name="key">密钥(32位)</param> /// <returns>字符串</returns> /// ///zh-cn/dotnet/api/system.security.cryptography.aescryptoserviceprovider.createencryptor?view=netframework-4.8public static string AESEncrypt(string input, string key, string iv){if (input == null) return input;byte[] keyBytes = Encoding.UTF8.GetBytes(key);using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider()){aesAlg.Key = keyBytes;aesAlg.IV = Encoding.UTF8.GetBytes(iv);aesAlg.Mode = CipherMode.ECB;aesAlg.Padding = PaddingMode.PKCS7;ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.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 Encoding.UTF8.GetString(bytes);return ByteArrayToHexString(bytes);//return Convert.ToBase64String(msEncrypt.ToArray());}}}}/// <summary>/// 使用系统默认的key和iv进行加密/// </summary>/// <param name="input">待加密的string</param>/// <returns>加密后的string</returns>public static string AESEncrypt(string input){return AESEncrypt(input, DEFAULT_AES_KEY.Substring(0, 32), DEFAULT_AES_IV.Substring(0, 16));}///zh-cn/dotnet/api/system.security.cryptography.aescryptoserviceprovider.createencryptor?view=netframework-4.8/// <summary> /// AES解密 /// </summary> /// <param name="input">密文字节数组</param> /// <param name="key">密钥(32位)</param> /// <returns>返回解密后的字符串</returns>public static string AESDecrypt(string input, string key, string iv){if (input == null) return input;//byte[] inputBytes = Convert.FromBase64String(input);byte[] inputBytes = HexStringToByteArray(input);//byte[] inputBytes = Encoding.UTF8.GetBytes(input);byte[] keyBytes = Encoding.UTF8.GetBytes(key);using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider()){aesAlg.Key = keyBytes;aesAlg.IV = Encoding.UTF8.GetBytes(iv);aesAlg.Mode = CipherMode.ECB;aesAlg.Padding = PaddingMode.PKCS7;ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);using (MemoryStream msEncrypt = new MemoryStream(inputBytes)){using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, decryptor, CryptoStreamMode.Read)){using (StreamReader srEncrypt = new StreamReader(csEncrypt)){return srEncrypt.ReadToEnd();}}}}}/// <summary>/// 使用系统默认的key和iv进行解密/// </summary>/// <param name="input">待解密的string</param>/// <returns>解密后的string</returns>public static string AESDecrypt(string input){return AESDecrypt(input, DEFAULT_AES_KEY.Substring(0, 32), DEFAULT_AES_IV.Substring(0, 16));}/// <summary>/// 将指定的16进制字符串转换为byte数组/// </summary>/// <param name="s">16进制字符串(如:“7F 2C 4A”或“7F2C4A”都可以)</param>/// <returns>16进制字符串对应的byte数组</returns>public static byte[] HexStringToByteArray(string s){s = s.Replace(" ", "");byte[] buffer = new byte[s.Length / 2];for (int i = 0; i < s.Length; i += 2)buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);return buffer;}/// <summary>/// 将一个byte数组转换成一个格式化的16进制字符串/// </summary>/// <param name="data">byte数组</param>/// <returns>格式化的16进制字符串</returns>public static string ByteArrayToHexString(byte[] data){StringBuilder sb = new StringBuilder(data.Length * 3);foreach (byte b in data){//16进制数字sb.Append(Convert.ToString(b, 16).PadLeft(2, '0'));//16进制数字之间以空格隔开//sb.Append(Convert.ToString(b, 16).PadLeft(2, '0').PadRight(3, ' '));}return sb.ToString().ToUpper();}}}

测试代码和示例如下:

string destr = AESUtil.AESEncrypt("我是要加密的内容,且转为base64码的字符串,解密记得先转为对应!");//Console.WriteLine(enstr);//string destr = "FOyUSJ1YATG1qH2+kycS9ofTsH3mAieDNTGWr2g7y/cs2u/2WAerCwzT9FwCA2MmeGWzleoeT3em1PyForMifyPsHzDwuidJ8CSOZgyta1ODQzS+ogqiGVYCQTEgRhI/";//string destr = "14EC94489D580131B5A87DBE932712F687D3B07DE6022783353196AF683BCBF72CDAEFF65807AB0B0CD3F45C020363267865B395EA1E4F77A6D4FC85A2B3227F23EC1F30F0BA2749F0248E660CAD6B53834334BEA20AA219560241312046123F";string ret = AESUtil.AESDecrypt(destr);Console.WriteLine(ret);

注意事项和要点总结,

系统提供加密解密方法,都是操作密文的字节数组,

可能我们平时需要变成字符串密文,这里加密后得到密文数组,

加密后的密文数组,转为为字符串方式,常用转为base64或是上面自定义的方式,转为16进制字符串

那么解密也需要对应方式,将字符串按照同样的方式,转化为数组,这个一定要保持一致,

否则报错如下:

总结:采用相同密钥,初始化变量,明文,不管前端还是后台得到相同结果,那么可以用做安全校验,提升安全性

(当然密钥写在脚本中,前端加密其实安全性有限,这里博主不做讨论,/question/373064057)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。