C#实现AES(Rijndael算法)加密解密

来源:互联网 发布:斗蟹软件下载 编辑:程序博客网 时间:2024/05/18 02:50

AES 


AES 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法

Rijndael(读作rain-dahl)是由美国国家标准与技术协会(NIST)所选的高级加密标准(AES)的候选算法。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。


Rijndael 算法首先是一个密钥分组加密的算法,通过置换(permutations )和替换(substitutions)迭代加密,进过多轮操作形成密文。


AES算是Rijndael算法的一种特殊实现,选的分组为128bit(16字节),密钥可以使用128、192 和 256bit三种,而Rijndael使用的密钥和区块长度可以是32位的整数倍,以128位为下限,256比特为上限。加密过程中使用的密钥是由Rijndael密钥生成方案产生。


AES加密过程是在一个4×4的字节矩阵上运作,这个矩阵又称为“状态(state)”,其初值就是一个明文区块(矩阵中一个元素大小就是明文区块中的一个Byte)。(Rijndael加密法因支持更大的区块,其矩阵行数可视情况增加)加密时,各轮AES加密循环(除最后一轮外)均包含4个步骤:
AddRoundKey — 矩阵中的每一个字节都与该次轮秘钥(round key)做XOR运算;每个子密钥由密钥生成方案产生。
SubBytes — 通过非线性的替换函数,用查找表的方式把每个字节替换成对应的字节。
ShiftRows — 将矩阵中的每个横列进行循环式移位。
MixColumns — 为了充分混合矩阵中各个直行的操作。这个步骤使用线性转换来混合每列的四个字节。


RijndaelManager代码实现

using System;  using System.Collections.Generic;  using System.Text;  using System.Security.Cryptography;  using System.IO;    namespace Csharp  {      class AESHelper      {          /// <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);          }            /// <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="plainBytes">被加密的明文</param>          /// <param name="key">密钥</param>          /// <returns>密文</returns>          public static string AESEncrypt(String Data, String Key)          {              MemoryStream mStream = new MemoryStream();              RijndaelManaged aes = new RijndaelManaged();                byte[] plainBytes = Encoding.UTF8.GetBytes(Data);              Byte[] bKey = new Byte[32];              Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);                aes.Mode = CipherMode.ECB;              aes.Padding = PaddingMode.PKCS7;              aes.KeySize = 128;              //aes.Key = _key;              aes.Key = bKey;              //aes.IV = _iV;              CryptoStream cryptoStream = new CryptoStream(mStream, aes.CreateEncryptor(), CryptoStreamMode.Write);              try              {                  cryptoStream.Write(plainBytes, 0, plainBytes.Length);                  cryptoStream.FlushFinalBlock();                  return Convert.ToBase64String(mStream.ToArray());              }              finally              {                  cryptoStream.Close();                  mStream.Close();                  aes.Clear();              }          }              /// <summary>          /// AES解密(无向量)          /// </summary>          /// <param name="encryptedBytes">被加密的明文</param>          /// <param name="key">密钥</param>          /// <returns>明文</returns>          public static string AESDecrypt(String Data, String Key)          {              Byte[] encryptedBytes = Convert.FromBase64String(Data);              Byte[] bKey = new Byte[32];              Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);                            MemoryStream mStream = new MemoryStream(encryptedBytes);              //mStream.Write( encryptedBytes, 0, encryptedBytes.Length );              //mStream.Seek( 0, SeekOrigin.Begin );              RijndaelManaged aes = new RijndaelManaged();              aes.Mode = CipherMode.ECB;              aes.Padding = PaddingMode.PKCS7;              aes.KeySize = 128;              aes.Key = bKey;              //aes.IV = _iV;              CryptoStream cryptoStream = new CryptoStream(mStream, aes.CreateDecryptor(), CryptoStreamMode.Read);              try              {                  byte[] tmp = new byte[encryptedBytes.Length + 32];                  int len = cryptoStream.Read(tmp, 0, encryptedBytes.Length + 32);                  byte[] ret = new byte[len];                  Array.Copy(tmp, 0, ret, 0, len);                  return Encoding.UTF8.GetString(ret);              }              finally              {                  cryptoStream.Close();                  mStream.Close();                  aes.Clear();              }          }      }  }  

AesManager代码实现

using System;using System.IO;using System.Security.Cryptography;namespace Aes_Example{    class AesExample    {        public static void Main()        {            try            {                string original = "Here is some data to encrypt!";                // Create a new instance of the AesManaged                // class.  This generates a new key and initialization                 // vector (IV).                using (AesManaged myAes = new AesManaged())                {                    // Encrypt the string to an array of bytes.                    byte[] encrypted = EncryptStringToBytes_Aes(original, myAes.Key, myAes.IV);                    // Decrypt the bytes to a string.                    string roundtrip = DecryptStringFromBytes_Aes(encrypted, myAes.Key, myAes.IV);                    //Display the original data and the decrypted data.                    Console.WriteLine("Original:   {0}", original);                    Console.WriteLine("Round Trip: {0}", roundtrip);                }            }            catch (Exception e)            {                Console.WriteLine("Error: {0}", e.Message);            }        }        static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)        {            // Check arguments.            if (plainText == null || plainText.Length <= 0)                throw new ArgumentNullException("plainText");            if (Key == null || Key.Length <= 0)                throw new ArgumentNullException("Key");            if (IV == null || IV.Length <= 0)                throw new ArgumentNullException("IV");            byte[] encrypted;            // Create an AesManaged object            // with the specified key and IV.            using (AesManaged aesAlg = new AesManaged())            {                aesAlg.Key = Key;                aesAlg.IV = IV;                // Create a decrytor to perform the stream transform.                ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);                // Create the streams used for encryption.                using (MemoryStream msEncrypt = new MemoryStream())                {                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))                    {                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))                        {                            //Write all data to the stream.                            swEncrypt.Write(plainText);                        }                        encrypted = msEncrypt.ToArray();                    }                }            }            // Return the encrypted bytes from the memory stream.            return encrypted;        }        static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV)        {            // Check arguments.            if (cipherText == null || cipherText.Length <= 0)                throw new ArgumentNullException("cipherText");            if (Key == null || Key.Length <= 0)                throw new ArgumentNullException("Key");            if (IV == null || IV.Length <= 0)                throw new ArgumentNullException("IV");            // Declare the string used to hold            // the decrypted text.            string plaintext = null;            // Create an AesManaged object            // with the specified key and IV.            using (AesManaged aesAlg = new AesManaged())            {                aesAlg.Key = Key;                aesAlg.IV = IV;                // Create a decrytor to perform the stream transform.                ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);                // Create the streams used for decryption.                using (MemoryStream msDecrypt = new MemoryStream(cipherText))                {                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))                    {                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))                        {                            // Read the decrypted bytes from the decrypting stream                            // and place them in a string.                            plaintext = srDecrypt.ReadToEnd();                        }                    }                }            }            return plaintext;        }    }}