AES对称加密算法下有好多种算法,往往很难做到垮语言的加密解密,本文提供一套C#和Node.js可以相互加密解密通用的代码之aes-256-cbc算法:
1、AES所有的钥匙必须 128位(16字节),192位(24字节)或256位(32字节)长
2、有几种操作模式,每个都有不同的优点和缺点。一般来说,建议用CBC和CTR模式。不推荐ECB(据说完整性不好)
aes-256-cbc C#代码
using System.Security.Cryptography;
public class AES { //默认密钥向量 private static byte[] _vector = { 0x41, 0x72, 0x65, 0x79, 0x6F, 0x75, 0x6E, 0x79, 0x53, 0x6E, 0x6F, 0x77, 0x6D, 0x61, 0x6E, 0x3F }; /// <summary> /// AES加密 /// </summary> /// <param name="encryptString">要加密的字符</param> /// <param name="encryptKey">对应的密钥(不可为中文,不能超过32个字符,超过32个字符的截取前32个字符)</param> /// <returns>返回Base64格式的字符串</returns> public static string Encode(string encryptString, string encryptKey) { if (string.IsNullOrEmpty(encryptString)) { throw new ArgumentNullException("参数encryptString为空!"); } if (string.IsNullOrEmpty(encryptKey)) { throw new ArgumentNullException("参数encryptKey为空!"); } if(encryptKey.Length > 32) encryptKey = StringUtility.CutString(encryptKey, 0, 32); if (encryptKey.Length < 32) encryptKey = encryptKey.PadRight(32, '0'); RijndaelManaged rijndaelProvider = new RijndaelManaged(); rijndaelProvider.Key = Encoding.UTF8.GetBytes(encryptKey); rijndaelProvider.IV = _vector; rijndaelProvider.Padding = PaddingMode.PKCS7; // 填充模式 ICryptoTransform rijndaelEncrypt = rijndaelProvider.CreateEncryptor(); byte[] inputData = Encoding.UTF8.GetBytes(encryptString); byte[] encryptedData = rijndaelEncrypt.TransformFinalBlock(inputData, 0, inputData.Length); return Convert.ToBase64String(encryptedData); } /// <summary> /// AES解密 /// </summary> /// <param name="decryptString">要解密的字符(该字符必须是已经加密过的Base64格式的字符串)</param> /// <param name="decryptKey">解密的密钥,该密钥要和加密的密钥一致(不可为中文,不能超过32个字符,超过32个字符的截取前32个字符)</param> /// <returns>解密后的字符串</returns> public static string Decode(string decryptString, string decryptKey) { try { if (string.IsNullOrEmpty(decryptString)) { throw new ArgumentNullException("参数encryptString为空!"); } if (string.IsNullOrEmpty(decryptKey)) { throw new ArgumentNullException("参数encryptKey为空!"); } if (decryptKey.Length > 32) decryptKey = StringUtility.CutString(decryptKey, 0, 32); if (decryptKey.Length < 32) decryptKey = decryptKey.PadRight(32, '0'); RijndaelManaged rijndaelProvider = new RijndaelManaged(); rijndaelProvider.Key = Encoding.UTF8.GetBytes(decryptKey); rijndaelProvider.IV = _vector; rijndaelProvider.Padding = PaddingMode.PKCS7; // 填充模式 ICryptoTransform rijndaelDecrypt = rijndaelProvider.CreateDecryptor(); byte[] inputData = Convert.FromBase64String(decryptString); byte[] decryptedData = rijndaelDecrypt.TransformFinalBlock(inputData, 0, inputData.Length); return Encoding.UTF8.GetString(decryptedData); } catch { return ""; } } public static string Decode(string decryptString, string decryptKey, byte[] my_vector) { try { if (string.IsNullOrEmpty(decryptString)) { throw new ArgumentNullException("参数encryptString为空!"); } if (string.IsNullOrEmpty(decryptKey)) { throw new ArgumentNullException("参数encryptKey为空!"); } if (decryptKey.Length > 32) decryptKey = StringUtility.CutString(decryptKey, 0, 32); if (decryptKey.Length < 32) decryptKey = decryptKey.PadRight(32, '0'); RijndaelManaged rijndaelProvider = new RijndaelManaged(); rijndaelProvider.Key = Encoding.UTF8.GetBytes(decryptKey); rijndaelProvider.IV = _vector; rijndaelProvider.Padding = PaddingMode.PKCS7; // 填充模式 ICryptoTransform rijndaelDecrypt = rijndaelProvider.CreateDecryptor(); byte[] inputData = Convert.FromBase64String(decryptString); byte[] decryptedData = rijndaelDecrypt.TransformFinalBlock(inputData, 0, inputData.Length); string uid = Encoding.UTF8.GetString(decryptedData); Guid id = Guid.Empty; if (Guid.TryParse(uid, out id)) //当前token解成功了 { return uid; } else { rijndaelProvider.IV = my_vector; rijndaelDecrypt = rijndaelProvider.CreateDecryptor(); decryptedData = rijndaelDecrypt.TransformFinalBlock(inputData, 0, inputData.Length); return Encoding.UTF8.GetString(decryptedData); } } catch { return ""; } } }
aes-256-cbc Node.js算法
var crypto = require('crypto'); /** * 加密方法 * @param key 加密key * @param iv 向量 * @param data 需要加密的数据 * @returns string */ var encrypt = function (key, iv, data) { var cipher = crypto.createCipheriv('aes-256-cbc', key, iv); var crypted = cipher.update(data, 'utf8', 'binary'); crypted += cipher.final('binary'); crypted = new Buffer(crypted, 'binary').toString('base64'); return crypted; }; /** * 解密方法 * @param key 解密的key * @param iv 向量 * @param crypted 密文 * @returns string */ var decrypt = function (key, iv, crypted) { crypted = new Buffer(crypted, 'base64').toString('binary'); var decipher = crypto.createDecipheriv('aes-256-cbc', key, iv); var decoded = decipher.update(crypted, 'binary', 'utf8'); decoded += decipher.final('utf8'); return decoded; }; var key = 'mobile987DEF@joyschool.cn0000000'; console.log('加密的key:', key.toString('hex')); var iv = 'AreyounySnowman?'; console.log('加密的iv:', iv); var data = "5c3bb4fe-2fcc-49b7-b58a-10520a8a0fb2"; console.log("需要加密的数据:", data); var crypted = encrypt(key, iv, data); console.log("数据加密后:", crypted); var dec = decrypt(key, iv, crypted); console.log("数据解密后:", dec);
本文原创,转载注明出处!