美文网首页C#.NET
C#中AES加密的实现

C#中AES加密的实现

作者: 画星星高手 | 来源:发表于2018-03-15 09:42 被阅读43次

    AES算法简介

    高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。

    该算法为比利时密码学家Joan Daemen和Vincent Rijmen所设计,结合两位作者的名字,以Rijndael为名投稿高级加密标准的甄选流程。(Rijndael的发音近于"Rhine doll")

    AES加密过程

    AES加密过程是在一个4×4的字节矩阵上运作,这个矩阵又称为“体(state)”,其初值就是一个明文区块(矩阵中一个元素大小就是明文区块中的一个Byte)。(Rijndael加密法因支持更大的区块,其矩阵行数可视情况增加)加密时,各轮AES加密循环(除最后一轮外)均包含4个步骤:

    1. AddRoundKey—矩阵中的每一个字节都与该次回合密钥(round key)做XOR运算;每个子密钥由密钥生成方案产生。
    2. SubBytes—通过一个非线性的替换函数,用查找表的方式把每个字节替换成对应的字节。
    3. ShiftRows—将矩阵中的每个横列进行循环式移位。
    4. MixColumns—为了充分混合矩阵中各个直行的操作。这个步骤使用线性转换来混合每内联的四个字节。最后一个加密循环中省略MixColumns步骤,而以另一个AddRoundKey取代。

    C#代码实现

    定义默认密钥向量

    private static byte[] _aesKetByte = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
    private static string _aesKeyStr = Encoding.UTF8.GetString(_aesKetByte);
    

    随机生成密钥

    public static byte[] GetIv(int n)
    {
        char[] arrChar = new char[]{
           'a','b','d','c','e','f','g','h','i','j','k','l','m','n','p','r','q','s','t','u','v','w','z','y','x',
           '0','1','2','3','4','5','6','7','8','9',
           'A','B','C','D','E','F','G','H','I','J','K','L','M','N','Q','P','R','T','S','V','U','W','X','Y','Z'
        };
    
        StringBuilder num = new StringBuilder();
    
        Random rnd = new Random(DateTime.Now.Millisecond);
        for (int i = 0; i < n; i++)
        {
            num.Append(arrChar[rnd.Next(0, arrChar.Length)].ToString());
        }
    
        _aesKetByte = Encoding.UTF8.GetBytes(num.ToString());
        return _aesKetByte;
    }
    

    AES加密

    /// <summary>
    /// AES加密
    /// </summary>
    /// <param name="Data">被加密的明文</param>
    /// <param name="Key">密钥</param>
    /// <param name="Vector">向量</param>
    /// <returns>密文</returns>
    public static String AESEncrypt(String Data, String Key, String Vector)
    {
        Byte[] plainBytes = Encoding.UTF8.GetBytes(Data);
    
        Byte[] bKey = new Byte[32];
        Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);
        Byte[] bVector = new Byte[16];
        Array.Copy(Encoding.UTF8.GetBytes(Vector.PadRight(bVector.Length)), bVector, bVector.Length);
    
        Byte[] Cryptograph = null; // 加密后的密文
    
        Rijndael Aes = Rijndael.Create();
        try
        {
            // 开辟一块内存流
            using (MemoryStream Memory = new MemoryStream())
            {
                // 把内存流对象包装成加密流对象
                using (CryptoStream Encryptor = new CryptoStream(Memory,
                Aes.CreateEncryptor(bKey, bVector),
                CryptoStreamMode.Write))
                {
                    // 明文数据写入加密流
                    Encryptor.Write(plainBytes, 0, plainBytes.Length);
                    Encryptor.FlushFinalBlock();
    
                    Cryptograph = Memory.ToArray();
                }
            }
        }
        catch
        {
            Cryptograph = null;
        }
    
        return Convert.ToBase64String(Cryptograph);
    }
    

    AES解密

    /// <summary>
    /// AES解密
    /// </summary>
    /// <param name="Data">被解密的密文</param>
    /// <param name="Key">密钥</param>
    /// <param name="Vector">向量</param>
    /// <returns>明文</returns>
    public static String AESDecrypt(String Data, String Key, String Vector)
    {
        Byte[] encryptedBytes = Convert.FromBase64String(Data);
        Byte[] bKey = new Byte[32];
        Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);
        Byte[] bVector = new Byte[16];
        Array.Copy(Encoding.UTF8.GetBytes(Vector.PadRight(bVector.Length)), bVector, bVector.Length);
    
        Byte[] original = null; // 解密后的明文
    
        Rijndael Aes = Rijndael.Create();
        try
        {
            // 开辟一块内存流,存储密文
            using (MemoryStream Memory = new MemoryStream(encryptedBytes))
            {
                // 把内存流对象包装成加密流对象
                using (CryptoStream Decryptor = new CryptoStream(Memory,
                Aes.CreateDecryptor(bKey, bVector),
                CryptoStreamMode.Read))
                {
                    // 明文存储区
                    using (MemoryStream originalMemory = new MemoryStream())
                    {
                        Byte[] Buffer = new Byte[1024];
                        Int32 readBytes = 0;
                        while ((readBytes = Decryptor.Read(Buffer, 0, Buffer.Length)) > 0)
                        {
                            originalMemory.Write(Buffer, 0, readBytes);
                        }
    
                        original = originalMemory.ToArray();
                    }
                }
            }
        }
        catch
        {
            original = null;
        }
        return Encoding.UTF8.GetString(original);
    }
    

    使用默认向量加解密

    /// <summary>
    /// AES加密(无向量)
    /// </summary>
    /// <param name="Data">被加密的明文</param>
    /// <param name="Key">密钥</param>
    /// <returns>密文</returns>
    public static string AESEncrypt(String Data, String Key)
    {
        return AESEncrypt(Data, Key, _aesKeyStr);
    
    }
    /// <summary>
    /// AES解密(无向量)
    /// </summary>
    /// <param name="Data">被加密的明文</param>
    /// <param name="Key">密钥</param>
    /// <returns>明文</returns>
    public static string AESDecrypt(String Data, String Key)
    {
        return AESDecrypt(Data, Key, _aesKeyStr);
    }
    

    了解更多有趣的操作请关注我的微信公众号:DealiAxy

    公众号:DealiAxy

    每一篇文章都在我的博客有收录:blog.deali.cn

    相关文章

      网友评论

        本文标题:C#中AES加密的实现

        本文链接:https://www.haomeiwen.com/subject/xnycqftx.html