【加密算法】AES

一、简介

AES(Advanced Encryption Standard):高级加密标准,是下一代的加密算法标准,速度快,安全级别高。

用AES加密2000年10月,NIST(美国国家标准和技术协会)宣布通过从15种候选算法中选出的一项新的密匙加密标准。Rijndael被选中成为将来的 AES。Rijndael是在1999年下半年,由研究员Joan Daemen 和 Vincent Rijmen 创建的。AES正日益成为加密各种形式的电子数据的实际标准。

美国标准与技术研究院(NIST)于2002年5月26日制定了新的高级加密标准(AES)规范。

AES算法基于排列和置换运算。排列是对数据重新进行安排,置换是将一个数据单元替换为另一个。

AES使用几种不同的方法来执行排列和置换运算。AES是一个迭代的、对称密钥分组的密码,它可以使用128、192和256位密钥,并且用128位(16字节)分组加密和解密数据。

与公共密钥加密使用密钥对不同,对称密钥密码使用相同的密钥加密和解密数据。通过分组密码返回的加密数据的位数与输入数据相同。迭代加密使用一个循环结构,在该循环中重复置换和替换输入数据。

二、实现

/// <summary>
/// AES加解密
/// ECB模式,偏移向量不起作用
/// 当前代码的密钥、偏移向量不可以含有中文
/// 如需跟java、php通用加解密,参数需一致
/// </summary>
public class AesHelper
{
    //默认密钥、初始化向量
    private static readonly string _Key = "Q3zmD8v^LWYu5QsX";   //默认密钥 长度可为16位、24位、32位
    private static readonly string _Vector = "figQi#gxIxqcnaKr";    //默认偏移向量 长度为16位

    /// <summary>
    /// AES加密
    /// 密码:默认
    /// 偏移量:默认
    /// 模式:CBC
    /// 填充:PKCS7
    /// 输出:Base64
    /// 编码:UTF8
    /// </summary>
    /// <param name="plaintext">明文</param>
    /// <returns>大写的密文</returns>
    public static string Encrypt(string plaintext)
    {
        return Encrypt(plaintext, _Key, _Vector);
    }

    /// <summary>
    /// AES加密
    /// 密码:默认
    /// 偏移量:默认
    /// 模式:CBC
    /// 填充:PKCS7
    /// 输出:自定义
    /// 编码:UTF8
    /// </summary>
    /// <param name="plaintext">明文</param>
    /// <returns>大写的密文</returns>
    public static string Encrypt(string plaintext, OutputMethod method)
    {
        return Encrypt(plaintext, _Key, _Vector, method);
    }


    /// <summary>
    /// AES加密
    /// 密码:自定义
    /// 偏移量:自定义
    /// 模式:CBC
    /// 填充:PKCS7
    /// 输出:Base64
    /// 编码:UTF8
    /// </summary>
    /// <param name="plaintext">明文</param>
    /// <param name="key">密码,16、24、32位,不含中文</param>
    /// <param name="iv">偏移量,16位,不含中文</param>
    /// <param name="cipher">加密模式</param>
    /// <param name="padding">填充</param>
    /// <returns></returns>
    public static string Encrypt(string plaintext, string key, string iv, OutputMethod method = OutputMethod.Base64, CipherMode cipher = CipherMode.CBC, PaddingMode padding = PaddingMode.PKCS7)
    {
        if (String.IsNullOrEmpty(plaintext))
        {
            throw new ArgumentNullException("明文不能为空");
        }

        Encoding encoding = Encoding.UTF8;
        byte[] byteContent = encoding.GetBytes(plaintext);
        byte[] byteKey = encoding.GetBytes(key);
        byte[] byteIV = encoding.GetBytes(iv);

        Rijndael rjd = Rijndael.Create();
        rjd.Key = byteKey;
        rjd.IV = byteIV;
        rjd.Mode = cipher;
        rjd.Padding = padding;

        using (MemoryStream ms = new MemoryStream())
        {
            CryptoStream cStream = new CryptoStream(ms, rjd.CreateEncryptor(), CryptoStreamMode.Write);
            cStream.Write(byteContent, 0, byteContent.Length);
            cStream.FlushFinalBlock();

            byte[] result = ms.ToArray();
            return EadUtil.Output(result, method);
        }
    }

    /// <summary>
    /// AES解密
    /// 密码:默认
    /// 偏移量:默认
    /// 模式:CBC
    /// 填充:PKCS7
    /// 编码:UTF8
    /// </summary>
    /// <param name="ciphertext">密文</param>
    /// <returns>返回明文</returns>
    public static string Decrypt(string ciphertext)
    {
        return Decrypt(ciphertext, _Key, _Vector);
    }

    /// <summary>
    /// AES解密
    /// 密码:默认
    /// 偏移量:默认
    /// 模式:CBC
    /// 填充:PKCS7
    /// 编码:UTF8
    /// </summary>
    /// <param name="ciphertext">密文</param>
    /// <returns>返回明文</returns>
    public static string Decrypt(string ciphertext, OutputMethod method)
    {
        return Decrypt(ciphertext, _Key, _Vector, method);
    }

    /// <summary>
    /// AES解密
    /// 密码:自定义
    /// 偏移量:自定义
    /// 模式:CBC
    /// 填充:PKCS7
    /// 编码:UTF8
    /// </summary>
    /// <param name="ciphertext">密文</param>
    /// <param name="key">密码,16、24、32位,不含中文</param>
    /// <param name="iv">偏移量,16位,不含中文</param>
    /// <param name="cipher">加密模式</param>
    /// <param name="padding">填充</param>
    /// <returns></returns>
    public static string Decrypt(string ciphertext, string key, string iv, OutputMethod method = OutputMethod.Base64, CipherMode cipher = CipherMode.CBC, PaddingMode padding = PaddingMode.PKCS7)
    {
        if (String.IsNullOrEmpty(ciphertext))
        {
            throw new ArgumentNullException("密文不能为空");
        }

        byte[] buffer = EadUtil.Input(ciphertext, method);

        Encoding encoding = Encoding.UTF8;
        byte[] byteKey = encoding.GetBytes(key);
        byte[] byteIV = encoding.GetBytes(iv);

        Rijndael aes = Rijndael.Create();
        aes.Key = byteKey;
        aes.IV = byteIV;
        aes.Mode = cipher;
        aes.Padding = padding;

        using (MemoryStream ms = new MemoryStream())
        {
            CryptoStream cStream = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write);
            cStream.Write(buffer, 0, buffer.Length);
            cStream.FlushFinalBlock();
            ms.Close();
            return encoding.GetString(ms.ToArray());
        }
    }
}

点击查看 OutputMethod、EadUtil

posted @ 2018-12-11 16:13  a boy  阅读(409)  评论(0编辑  收藏  举报