AES加密算法

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);

本文原创,转载注明出处!

原文地址:https://www.cnblogs.com/xbblogs/p/6426041.html