C#实现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代码实现

  1. using System;

  2. using System.Collections.Generic;

  3. using System.Text;

  4. using System.Security.Cryptography;

  5. using System.IO;

  6. namespace Csharp

  7. {

  8. class AESHelper

  9. {

  10. /// <summary>

  11. /// AES加密

  12. /// </summary>

  13. /// <param name="Data">被加密的明文</param>

  14. /// <param name="Key">密钥</param>

  15. /// <param name="Vector">向量</param>

  16. /// <returns>密文</returns>

  17. public static String AESEncrypt(String Data, String Key, String Vector)

  18. {

  19. Byte[] plainBytes = Encoding.UTF8.GetBytes(Data);

  20. Byte[] bKey = new Byte[32];

  21. Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);

  22. Byte[] bVector = new Byte[16];

  23. Array.Copy(Encoding.UTF8.GetBytes(Vector.PadRight(bVector.Length)), bVector, bVector.Length);

  24. Byte[] Cryptograph = null; // 加密后的密文

  25. Rijndael Aes = Rijndael.Create();

  26. try

  27. {

  28. // 开辟一块内存流

  29. using (MemoryStream Memory = new MemoryStream())

  30. {

  31. // 把内存流对象包装成加密流对象

  32. using (CryptoStream Encryptor = new CryptoStream(Memory,

  33. Aes.CreateEncryptor(bKey, bVector),

  34. CryptoStreamMode.Write))

  35. {

  36. // 明文数据写入加密流

  37. Encryptor.Write(plainBytes, 0, plainBytes.Length);

  38. Encryptor.FlushFinalBlock();

  39. Cryptograph = Memory.ToArray();

  40. }

  41. }

  42. }

  43. catch

  44. {

  45. Cryptograph = null;

  46. }

  47. return Convert.ToBase64String(Cryptograph);

  48. }

  49. /// <summary>

  50. /// AES解密

  51. /// </summary>

  52. /// <param name="Data">被解密的密文</param>

  53. /// <param name="Key">密钥</param>

  54. /// <param name="Vector">向量</param>

  55. /// <returns>明文</returns>

  56. public static String AESDecrypt(String Data, String Key, String Vector)

  57. {

  58. Byte[] encryptedBytes = Convert.FromBase64String(Data);

  59. Byte[] bKey = new Byte[32];

  60. Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);

  61. Byte[] bVector = new Byte[16];

  62. Array.Copy(Encoding.UTF8.GetBytes(Vector.PadRight(bVector.Length)), bVector, bVector.Length);

  63. Byte[] original = null; // 解密后的明文

  64. Rijndael Aes = Rijndael.Create();

  65. try

  66. {

  67. // 开辟一块内存流,存储密文

  68. using (MemoryStream Memory = new MemoryStream(encryptedBytes))

  69. {

  70. // 把内存流对象包装成加密流对象

  71. using (CryptoStream Decryptor = new CryptoStream(Memory,

  72. Aes.CreateDecryptor(bKey, bVector),

  73. CryptoStreamMode.Read))

  74. {

  75. // 明文存储区

  76. using (MemoryStream originalMemory = new MemoryStream())

  77. {

  78. Byte[] Buffer = new Byte[1024];

  79. Int32 readBytes = 0;

  80. while ((readBytes = Decryptor.Read(Buffer, 0, Buffer.Length)) > 0)

  81. {

  82. originalMemory.Write(Buffer, 0, readBytes);

  83. }

  84. original = originalMemory.ToArray();

  85. }

  86. }

  87. }

  88. }

  89. catch

  90. {

  91. original = null;

  92. }

  93. return Encoding.UTF8.GetString(original);

  94. }

  95. /// <summary>

  96. /// AES加密(无向量)

  97. /// </summary>

  98. /// <param name="plainBytes">被加密的明文</param>

  99. /// <param name="key">密钥</param>

  100. /// <returns>密文</returns>

  101. public static string AESEncrypt(String Data, String Key)

  102. {

  103. MemoryStream mStream = new MemoryStream();

  104. RijndaelManaged aes = new RijndaelManaged();

  105. byte[] plainBytes = Encoding.UTF8.GetBytes(Data);

  106. Byte[] bKey = new Byte[32];

  107. Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);

  108. aes.Mode = CipherMode.ECB;

  109. aes.Padding = PaddingMode.PKCS7;

  110. aes.KeySize = 128;

  111. //aes.Key = _key;

  112. aes.Key = bKey;

  113. //aes.IV = _iV;

  114. CryptoStream cryptoStream = new CryptoStream(mStream, aes.CreateEncryptor(), CryptoStreamMode.Write);

  115. try

  116. {

  117. cryptoStream.Write(plainBytes, 0, plainBytes.Length);

  118. cryptoStream.FlushFinalBlock();

  119. return Convert.ToBase64String(mStream.ToArray());

  120. }

  121. finally

  122. {

  123. cryptoStream.Close();

  124. mStream.Close();

  125. aes.Clear();

  126. }

  127. }

  128. /// <summary>

  129. /// AES解密(无向量)

  130. /// </summary>

  131. /// <param name="encryptedBytes">被加密的明文</param>

  132. /// <param name="key">密钥</param>

  133. /// <returns>明文</returns>

  134. public static string AESDecrypt(String Data, String Key)

  135. {

  136. Byte[] encryptedBytes = Convert.FromBase64String(Data);

  137. Byte[] bKey = new Byte[32];

  138. Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);

  139. MemoryStream mStream = new MemoryStream(encryptedBytes);

  140. //mStream.Write( encryptedBytes, 0, encryptedBytes.Length );

  141. //mStream.Seek( 0, SeekOrigin.Begin );

  142. RijndaelManaged aes = new RijndaelManaged();

  143. aes.Mode = CipherMode.ECB;

  144. aes.Padding = PaddingMode.PKCS7;

  145. aes.KeySize = 128;

  146. aes.Key = bKey;

  147. //aes.IV = _iV;

  148. CryptoStream cryptoStream = new CryptoStream(mStream, aes.CreateDecryptor(), CryptoStreamMode.Read);

  149. try

  150. {

  151. byte[] tmp = new byte[encryptedBytes.Length + 32];

  152. int len = cryptoStream.Read(tmp, 0, encryptedBytes.Length + 32);

  153. byte[] ret = new byte[len];

  154. Array.Copy(tmp, 0, ret, 0, len);

  155. return Encoding.UTF8.GetString(ret);

  156. }

  157. finally

  158. {

  159. cryptoStream.Close();

  160. mStream.Close();

  161. aes.Clear();

  162. }

  163. }

  164. }

  165. }

AesManager代码实现

  1. using System;

  2. using System.IO;

  3. using System.Security.Cryptography;

  4. namespace Aes_Example

  5. {

  6. class AesExample

  7. {

  8. public static void Main()

  9. {

  10. try

  11. {

  12. string original = "Here is some data to encrypt!";

  13. // Create a new instance of the AesManaged

  14. // class. This generates a new key and initialization

  15. // vector (IV).

  16. using (AesManaged myAes = new AesManaged())

  17. {

  18. // Encrypt the string to an array of bytes.

  19. byte[] encrypted = EncryptStringToBytes_Aes(original, myAes.Key, myAes.IV);

  20. // Decrypt the bytes to a string.

  21. string roundtrip = DecryptStringFromBytes_Aes(encrypted, myAes.Key, myAes.IV);

  22. //Display the original data and the decrypted data.

  23. Console.WriteLine("Original: {0}", original);

  24. Console.WriteLine("Round Trip: {0}", roundtrip);

  25. }

  26. }

  27. catch (Exception e)

  28. {

  29. Console.WriteLine("Error: {0}", e.Message);

  30. }

  31. }

  32. static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)

  33. {

  34. // Check arguments.

  35. if (plainText == null || plainText.Length <= 0)

  36. throw new ArgumentNullException("plainText");

  37. if (Key == null || Key.Length <= 0)

  38. throw new ArgumentNullException("Key");

  39. if (IV == null || IV.Length <= 0)

  40. throw new ArgumentNullException("IV");

  41. byte[] encrypted;

  42. // Create an AesManaged object

  43. // with the specified key and IV.

  44. using (AesManaged aesAlg = new AesManaged())

  45. {

  46. aesAlg.Key = Key;

  47. aesAlg.IV = IV;

  48. // Create a decrytor to perform the stream transform.

  49. ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

  50. // Create the streams used for encryption.

  51. using (MemoryStream msEncrypt = new MemoryStream())

  52. {

  53. using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))

  54. {

  55. using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))

  56. {

  57. //Write all data to the stream.

  58. swEncrypt.Write(plainText);

  59. }

  60. encrypted = msEncrypt.ToArray();

  61. }

  62. }

  63. }

  64. // Return the encrypted bytes from the memory stream.

  65. return encrypted;

  66. }

  67. static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV)

  68. {

  69. // Check arguments.

  70. if (cipherText == null || cipherText.Length <= 0)

  71. throw new ArgumentNullException("cipherText");

  72. if (Key == null || Key.Length <= 0)

  73. throw new ArgumentNullException("Key");

  74. if (IV == null || IV.Length <= 0)

  75. throw new ArgumentNullException("IV");

  76. // Declare the string used to hold

  77. // the decrypted text.

  78. string plaintext = null;

  79. // Create an AesManaged object

  80. // with the specified key and IV.

  81. using (AesManaged aesAlg = new AesManaged())

  82. {

  83. aesAlg.Key = Key;

  84. aesAlg.IV = IV;

  85. // Create a decrytor to perform the stream transform.

  86. ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

  87. // Create the streams used for decryption.

  88. using (MemoryStream msDecrypt = new MemoryStream(cipherText))

  89. {

  90. using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))

  91. {

  92. using (StreamReader srDecrypt = new StreamReader(csDecrypt))

  93. {

  94. // Read the decrypted bytes from the decrypting stream

  95. // and place them in a string.

  96. plaintext = srDecrypt.ReadToEnd();

  97. }

  98. }

  99. }

  100. }

  101. return plaintext;

  102. }

  103. }

  104. }