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

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

  • 相关阅读:
    许家骏
    平均得分 【杭州电-HDOJ-2023】 附加题+详细说明
    百度之星的第二个问题
    kendo ui 单击取消编辑数据grid减少的原因和治疗方法的数据
    2013年第36周准备考下半年的项目管理师
    2013年第36周三杂记
    2013第36周二小结
    2013第36周星期一
    2013年9月1日下午
    2013年8月最后一天晚上
  • 原文地址:https://www.cnblogs.com/xbblogs/p/6426041.html
Copyright © 2020-2023  润新知