AES對稱加密算法下有好多種算法,每每很難作到垮語言的加密解密,本文提供一套C#和Node.js能夠相互加密解密通用的代碼之aes-256-cbc算法:算法
一、AES全部的鑰匙必須 128位(16字節),192位(24字節)或256位(32字節)長ide
二、有幾種操做模式,每一個都有不一樣的優勢和缺點。通常來講,建議用CBC和CTR模式。不推薦ECB(聽說完整性很差)ui
aes-256-cbc C#代碼加密
using System.Security.Cryptography;spa
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算法3d
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);
本文原創,轉載註明出處!code