【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
在报文传输的过程中,根据报文传输的形态,有两种形式,一种是明文传输,一种是加密传输。当然明文传输的时候,一般为了验证数据是否正确,还会添加一个crc校验。不过这和数据传输是否加密没有关系。另外一种则是加密传输,理论上任何加密的报文都是可以破解的,但这破解的时间则或长或短。如果key的长度足够长,那么可能穷尽一生,也无法破解特定的数据。或者就算破解了,可能也丧失了数据的时效性。
目前c# wpf自身的函数库就支持数据的加密和解密,对于我们来说能够正常使用就可以了,没有必要过度关注里面的原理部分。
1、准备测试界面
测试的界面不复杂,主要就是准备两个button和两个text。两个button负责加密和解密,而两个text分别表示原文和加密后的报文。
有兴趣的同学可以参考一下这个xaml文件,
<Window x:Class="WpfApp.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:WpfApp"mc:Ignorable="d"Title="MainWindow" Height="450" Width="600"><Grid><!-- Your UI elements go here --><StackPanel Margin="10,10,10,10"><Button Content="EncryptButton" Height="60" Click="EncryptButton_Click"/><Label Height="20"/><Button Content="DecryptButton" Height="60" Click="DecryptButton_Click"/><Label Height="20"/><TextBox x:Name="plaintextTextBox" Height="60" Text=""/><Label Height="20"/><TextBox x:Name="encryptedTextBox" Height="60" Text=""/></StackPanel></Grid>
</Window>
2、引入加解密库
前面我们说过,本身c#自带了加密库,所以我们直接引用进来就可以了。
using System.Security.Cryptography;
3、准备加密key和iv
报文加密与解密,最重要的内容就是密钥的部分。当然,我们这里只是一般的加解密,随意可以用随机数的方法生成密钥。如果是复杂一点的场景,一般使用rsa加解密,即加密的人用公钥来进行数据加密处理,而解密的人则拿着私钥来进行数据解密。
private byte[] Key; // Replace with a secure keyprivate byte[] IV; // Replace with a secure IV// generate keypublic static byte[] GetRandomKey(int keySize){using (var rng = new RNGCryptoServiceProvider()){byte[] key = new byte[keySize / 8]; // Key size is in bits, so convert to bytesrng.GetBytes(key);return key;}}// generate IVpublic static byte[] GetRandomIV(int blockSize){using (var rng = new RNGCryptoServiceProvider()){byte[] iv = new byte[blockSize / 8]; // Block size is in bits, so convert to bytesrng.GetBytes(iv);return iv;}}public MainWindow(){InitializeComponent();Key = GetRandomKey(128);IV = GetRandomIV(128);}
这里的Key和Iv大家可以看成双密钥去理解就可以了,相当于给一个门安了两把锁。
4、数据加密
等密钥弄好之后,就可以开始做数据加密了,相关过程有些拗口,说起来就是首先生成一个Aes对象,接着用Aes对象生成IcryptoTransform,完了之后借助于MemoryStream对象、CryptoStream对象、StreamWriter对象对报文进行加密处理。虽然自己也不知道这个过程是什么意思,但是确实可以实现数据的加密。
// encrypt dataprivate void EncryptButton_Click(object sender, RoutedEventArgs e){string plaintext = plaintextTextBox.Text;if(plaintext.Length == 0){return;}string encryptedText = EncryptString(plaintext, Key, IV);encryptedTextBox.Text = encryptedText;}private string EncryptString(string plainText, byte[] key, byte[] iv){using (Aes aesAlg = Aes.Create()){aesAlg.Key = key;aesAlg.IV = iv;ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);using (MemoryStream msEncrypt = new MemoryStream()){using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)){using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)){swEncrypt.Write(plainText);}}return Convert.ToBase64String(msEncrypt.ToArray());}}}
5、数据解密
数据解密和加密的过程是差不多的,唯一的区别就是在创建ICryptoTransform的时候,调用的是aesAlg.CreateDecryptor,而不是aesAlg.CreateEncryptor。
// decrypt dataprivate void DecryptButton_Click(object sender, RoutedEventArgs e){string encryptedText = encryptedTextBox.Text;if(encryptedText.Length == 0){return;}string decryptedText = DecryptString(encryptedText, Key, IV);plaintextTextBox.Text = decryptedText;}private string DecryptString(string cipherText, byte[] key, byte[] iv){using (Aes aesAlg = Aes.Create()){aesAlg.Key = key;aesAlg.IV = iv;ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);using (MemoryStream msDecrypt = new MemoryStream(Convert.FromBase64String(cipherText))){using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)){using (StreamReader srDecrypt = new StreamReader(csDecrypt)){return srDecrypt.ReadToEnd();}}}}}
6、软件测试
测试就更简单了,主要看编译完成之后,验证数据是否可以从原文变成加密文。没问题之后,再看下是不是可以从加密文变成原文。