上一章我们举例了官方给出的一个AES加密例程,我们从官方的例程可以看出,这例程对文档类型的文件进行加密是比较合适的。
但有时候,我们需要对一小段数据进行加密,例如通过序列号加密生成产品加密后的序列号,用于遥控与主机间的RF通信,这就是纯粹的16进制数进行加密了。比如汽车遥控,家居遥控等等,这些产品序列号是对所有用户透明的,如果不进行加密,通信信息很容易被拦截。为解决这一问题,我们这里介绍一下aes128加密16字节序列号:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Security.Cryptography; namespace aesDemo { class Program { static void Main(string[] args) { var keyBuf = "1111111111111111"; var valueBuf = Encoding.UTF8.GetBytes("2222222222222222"); using(var aes=new RijndaelManaged()) { aes.IV = Encoding.UTF8.GetBytes(keyBuf); aes.Key = Encoding.UTF8.GetBytes(keyBuf); aes.Mode = CipherMode.ECB; aes.Padding = PaddingMode.None; var cryptoTransform = aes.CreateEncryptor(); var resultBuff = cryptoTransform.TransformFinalBlock(valueBuf, 0, valueBuf.Length); Console.WriteLine(resultBuff.Length); foreach (byte i in resultBuff) Console.WriteLine("{0:X2}", i); } Console.ReadLine(); } } }
编译运行:
我们校验一下我们的结果:
说明我们的算法没问题。下面我们简化一下:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Security.Cryptography; 7 8 namespace aesDemo 9 { 10 class Program 11 { 12 static void Main(string[] args) 13 { 14 byte[] plaintext = new byte[] { 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32 }; 15 using(var aes=new RijndaelManaged()) 16 { 17 aes.IV = new byte[16]; 18 aes.Key = new byte[]{0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,}; 19 aes.Mode = CipherMode.ECB; 20 aes.Padding = PaddingMode.None; 21 var cryptoTransform = aes.CreateEncryptor(); 22 var resultBuff = cryptoTransform.TransformFinalBlock(plaintext, 0, plaintext.Length); 23 foreach (byte i in resultBuff) 24 Console.WriteLine("{0:X2}", i); 25 } 26 Console.ReadLine(); 27 } 28 } 29 }
这里有几个地方需要讲解一下的:
- using System.Security.Cryptography; 调用系统安全加密算法空间命名,对于这个官方给出的解释如下:namespace provides cryptographic services, including secure encoding and decoding of data, and many other operations, such as hashing, generation of random values, and authentication.
- 创建 RijndaelManaged 类,通过这个类,我们可以配置加密参数;
- aes.Mode = CipherMode.ECB; 设置对称算法中填充的模式,这里因为我们填充参数设置为none( aes.Padding = PaddingMode.None; ),所以该参数也可以不进行设置,或采用默认值CBC。
- 填充默认是填充为32字节的,因为我们只需用到16字节,所以我们可以设置其值为不填充 aes.Padding = PaddingMode.None; 当然你不做处理也是可以的,因为只要你提取前面的16字节,而忽略后面的16字节就好了。
至此,对C# ase加密我们就讲解完了,当然C#加密方式还有很多种,这些都是包含在 System.Security.Cryptography; 中,有兴趣的,可以自行深入探讨。
最后我们得到:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Security.Cryptography; 7 8 namespace aesDemo 9 { 10 class Program 11 { 12 static void Main(string[] args) 13 { 14 byte[] plaintext = new byte[] { 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32 }; 15 using(var aes=new RijndaelManaged()) 16 { 17 aes.IV = new byte[16]; 18 aes.Key = new byte[]{0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,}; 19 aes.Mode = CipherMode.CBC; 20 aes.Padding = PaddingMode.None; 21 var cryptoTransform = aes.CreateEncryptor(); 22 var resultBuff = cryptoTransform.TransformFinalBlock(plaintext, 0, plaintext.Length); 23 foreach (byte i in resultBuff) 24 Console.WriteLine("{0:X2}", i); 25 } 26 Console.ReadLine(); 27 } 28 } 29 }
下面我们接着说一下如何解密:
我们知道加密需要创建加密实例 var cryptoTransform = aes.CreateEncryptor(); 同样,解密也是一样的: cryptoTransform = aes.CreateDecryptor(); 接着按部就班,直接将需要解密的密文传入解密函数运算即可:
resultBuff = cryptoTransform.TransformFinalBlock(resultBuff, 0, resultBuff.Length);
最后总结代码:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Security.Cryptography; 7 8 namespace aesDemo 9 { 10 class Program 11 { 12 static void Main(string[] args) 13 { 14 byte[] plaintext = new byte[] { 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32 }; 15 using(var aes=new RijndaelManaged()) 16 { 17 aes.IV = new byte[16]; 18 aes.Key = new byte[]{0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31}; 19 //aes.Mode = CipherMode.CBC; 20 aes.Padding = PaddingMode.None; 21 var cryptoTransform = aes.CreateEncryptor(); 22 byte[] resultBuff = cryptoTransform.TransformFinalBlock(plaintext, 0, plaintext.Length); 23 foreach (byte i in resultBuff) 24 Console.Write("{0:X2}", i); 25 Console.WriteLine(); 26 cryptoTransform = aes.CreateDecryptor(); 27 resultBuff = cryptoTransform.TransformFinalBlock(resultBuff, 0, resultBuff.Length); 28 foreach (byte i in resultBuff) 29 Console.Write("{0:X2}", i); 30 } 31 Console.ReadLine(); 32 } 33 } 34 }
编译运行:
End.
谢谢.