文章目录
- 1 代码
- 1.1 定义Aes加密类块
- 1.2 在主函数中调用
- 2 获取Key和IV
- 2.1 基本方法
- 2.2 自定义Key
- 2.3 技术方面的原理
参考文章: C#软件加密实例? 。
参考官文: Aes 类。
在使用C#的自带的System.Security.Cryptography.Aes
模块进行加密和解密时,需要注意的点是:定义用于对称算法的密钥Key
和初始化向量IV
。
如果不定义,就算是对相同字符串加密,每次得到的加密结果也都不一样。
1 代码
1.1 定义Aes加密类块
using System.IO;
using System.Security.Cryptography;namespace Encryption
{internal class AesModule{Aes myAes = null;public AesModule(){// 创建一个Aes对象myAes = Aes.Create();// 【key的值获取方法见2.1】 myAes.Key = new byte[32] { 0xDD, 0xB7, 0xAA, 0xE5, 0xC6, 0x68, 0x95, 0x39, 0x72, 0x7C, 0x7F, 0xDC, 0x5B, 0xC9, 0x77, 0x21, 0x62, 0x59, 0xC4, 0x92, 0xBC, 0x7D, 0x44, 0xA7, 0x3D, 0x02, 0x37, 0x7B, 0x3C, 0x19, 0xEB, 0x7F };// 【IV的值获取方法见2.1】myAes.IV = new byte[16] { 0x84, 0xAA, 0xCD, 0x08, 0x21, 0xCE, 0x4D, 0xA7, 0x7B, 0x34, 0xD9, 0x9F, 0x28, 0x51, 0x8A, 0xEB };}~AesModule(){myAes.Dispose();}/// <summary>/// 将字符串加密为字节数组/// </summary>/// <param name="original">待加密的字符串</param>/// <returns>加密好的字节数组</returns>public byte[] EncryptAes(string original){if (original == null || original.Length <= 0) return null;byte[] encrypted;// 创建一个加密器来执行流转换。ICryptoTransform encryptor = myAes.CreateEncryptor(myAes.Key, myAes.IV);// 创建加密流。using (MemoryStream msEncrypt = new MemoryStream()){using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)){using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)){//将原始文本写入流。swEncrypt.Write(original);}encrypted = msEncrypt.ToArray();}}return encrypted;}/// <summary>/// 将字节数组解密为字符串/// </summary>/// <param name="bArr">待解密的字节数组</param>/// <returns>解密好的字符串</returns>public string DecryptAes(byte[] bArr){if (bArr == null || bArr.Length <= 0) return null;string plaintext = null;ICryptoTransform decryptor = myAes.CreateDecryptor(myAes.Key, myAes.IV);using (MemoryStream msDecrypt = new MemoryStream(bArr)){using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)){using (StreamReader srDecrypt = new StreamReader(csDecrypt)){// 从解密流中读取解密的字节。plaintext = srDecrypt.ReadToEnd();}}}return plaintext;}}
}
1.2 在主函数中调用
internal class Program
{static void Main(string[] args){string original = "Here is some data to encrypt!";AesModule aes = new AesModule(); // 创建自定义Aes模块的对象Console.WriteLine("Original: {0}", original);byte[] bArr = aes.EncryptAes(original); // 加密Console.WriteLine("Encrypted: {0}", BitConverter.ToString(bArr));Console.WriteLine("Decrypted: {0}", aes.DecryptAes(bArr)); // 解密Console.ReadLine();}
}
调用结果:
Original: Here is some data to encrypt!
Encrypted: 6B-AB-9D-2A-54-16-59-1B-B7-5F-5C-F5-43-6B-D0-C2-E3-6A-72-98-8D-42-99-D9-38-DC-20-09-9C-94-6B-27
Decrypted: Here is some data to encrypt!
2 获取Key和IV
2.1 基本方法
其实方法就是:
定义Aes对象,然后调用它的函数GenerateXXX()
方法,来生成Key和IV,并且写死到程序中。
internal class demo
{static void Main(){ using (Aes myAes = Aes.Create()) // 定义Aes对象{myAes.GenerateKey(); // 生成keyConsole.WriteLine("Key"); PrintBytes(myAes.Key); myAes.GenerateIV(); // 生成IVConsole.WriteLine("IV");PrintBytes(myAes.IV);}Console.ReadLine();}/// <summary>/// 输出字节数组,加0x并按逗号分割/// </summary>/// <param name="bArr">待输出字节数组</param>static void PrintBytes(byte[] bArr){for (int i = 0; i < bArr.Length; i++){if (i != 0) Console.Write(",");Console.Write("0x" + bArr[i].ToString("X2")); // 其中"X2"表示以大写十六进制格式输出,并且占两个字符的宽度(不足两位时前面补0)}Console.WriteLine();}
}
得到结果(每次运行都不一样):
Key
0xDD,0xB7,0xAA,0xE5,0xC6,0x68,0x95,0x39,0x72,0x7C,0x7F,0xDC,0x5B,0xC9,0x77,0x21,0x62,0x59,0xC4,0x92,0xBC,0x7D,0x44,0xA7,0x3D,0x02,0x37,0x7B,0x3C,0x19,0xEB,0x7F
IV
0x84,0xAA,0xCD,0x08,0x21,0xCE,0x4D,0xA7,0x7B,0x34,0xD9,0x9F,0x28,0x51,0x8A,0xEB
将结果拷贝到代码中下述位置即可:
myAes.Key = new byte[32] { 【key】};
myAes.IV = new byte[16] {【IV】};
2.2 自定义Key
如果你想要生成自定义的Key,那么,也可以使用如下方法来生成。
byte[] key = Encoding.UTF8.GetBytes("Heisagoodboyandwillfindtruelove!");
PrintBytes(key);
会得到专属Key:
0x48,0x65,0x69,0x73,0x61,0x67,0x6F,0x6F,0x64,0x62,0x6F,0x79,0x61,0x6E,0x64,0x77,0x69,0x6C,0x6C,0x66,0x69,0x6E,0x64,0x74,0x72,0x75,0x65,0x6C,0x6F,0x76,0x65,0x21
2.3 技术方面的原理
这里仅略述该预定义AES类的使用原理:
Key定义了get-set函数,而且会自动生成Key,其源代码如下:
public virtual byte[] Key
{get{if (KeyValue == null){GenerateKey();}...}set{...KeyValue = (byte[])value.Clone();}
}
IV类似。