AES加密中向量長度是16個byte
密鑰長度有三種:16,24,32 單位byte
AES的區塊長度固定為128比特,密鑰長度則可以是128(6byte*8b),192(24*8)或256(32*8)比特;
加密后的輸出要轉為base64 ,為什么呢?因為base64所有字符都是可打印,加密后的字符轉為base64才能被人看見,在復制時候不容易漏掉
在C#中AES加密解密寫法有:
using System.Security.Cryptography;
using System.Text.RegularExpressions;
/// <summary> /// AES解密 /// </summary> /// <param name="decryptString">AES密文</param> /// <param name="key">秘鑰(44個字符)</param> /// <param name="ivString">向量(16個字符)</param> /// <returns></returns> public static string AES_Decrypt(string decryptString, string key, string ivString) { try { key = key.PadRight(32, ' '); RijndaelManaged aes = new RijndaelManaged(); byte[] iv = Encoding.UTF8.GetBytes(ivString.Substring(0,16)); aes.Key = Encoding.UTF8.GetBytes(key.Substring(0, 32)); aes.Mode = CipherMode.ECB; aes.IV = iv; aes.Padding = PaddingMode.PKCS7; // ICryptoTransform rijndaelDecrypt = aes.CreateDecryptor(); byte[] inputData = Convert.FromBase64String(decryptString); byte[] xBuff = rijndaelDecrypt.TransformFinalBlock(inputData, 0, inputData.Length); return Encoding.UTF8.GetString(xBuff); } catch (Exception ex) { throw; } } /// <summary> /// 加密 /// </summary> /// <param name="encriyptString">要被加密的字符串</param> /// <param name="key">秘鑰(44個字符)</param> /// <param name="ivString">向量長度(16個字符)</param> /// <returns></returns> public static string AES_Encrypt(string encriyptString, string key, string ivString) { key = key.PadRight(32, ' '); SymmetricAlgorithm aes = new RijndaelManaged(); byte[] iv = Encoding.UTF8.GetBytes(ivString.Substring(0,16)); aes.Key = Encoding.UTF8.GetBytes(key.Substring(0, 32)); aes.Mode = CipherMode.ECB; aes.IV = iv; aes.Padding = PaddingMode.PKCS7; // ICryptoTransform rijndaelEncrypt = aes.CreateEncryptor(); byte[] inputData = Encoding.UTF8.GetBytes(encriyptString); byte[] encryptedData = rijndaelEncrypt.TransformFinalBlock(inputData, 0, inputData.Length); return Convert.ToBase64String(encryptedData); } #endregion }
填充(Padding)和運算模式(Mode)也可以自定義,不同的值有不同的結果
下面是另一種寫法
/// <summary> /// AES加密算法 /// </summary> /// <param name="plainText">明文字符串</param> /// <param name="strKey">密鑰</param> /// <returns>返回加密后的密文字節數組</returns> public static byte[] AESEncrypt(string plainText, string strKey) { //分組加密算法 SymmetricAlgorithm des = Rijndael.Create(); byte[] inputByteArray = Encoding.UTF8.GetBytes(plainText);//得到需要加密的字節數組 //設置密鑰及密鑰向量 des.Key = Encoding.UTF8.GetBytes(strKey); des.IV = _key1; MemoryStream ms = new MemoryStream(); CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write); cs.Write(inputByteArray, 0, inputByteArray.Length); cs.FlushFinalBlock(); byte[] cipherBytes = ms.ToArray();//得到加密后的字節數組 cs.Close(); ms.Close(); return cipherBytes; } /// <summary> /// AES解密 /// </summary> /// <param name="cipherText">密文字節數組</param> /// <param name="strKey">密鑰</param> /// <returns>返回解密后的字符串</returns> public static byte[] AESDecrypt(byte[] cipherText, string strKey) { SymmetricAlgorithm des = Rijndael.Create(); des.Key = Encoding.UTF8.GetBytes(strKey); des.IV = _key1; byte[] decryptBytes = new byte[cipherText.Length]; MemoryStream ms = new MemoryStream(cipherText); CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Read); cs.Read(decryptBytes, 0, decryptBytes.Length); cs.Close(); ms.Close(); return decryptBytes; }
在和不同語言做解密解密對接的時間要注意對方使用的編碼格式、填充模式和運算模式,這幾點都是容易被忽略的,尤其是編碼格式。稍不注意就進坑了