【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
在报文传输的过程中,根据报文传输的形态,有两种形式,一种是明文传输,一种是加密传输。当然明文传输的时候,一般为了验证数据是否正确,还会添加一个crc校验。不过这和数据传输是否加密没有关系。另外一种则是加密传输,理论上任何加密的报文都是可以破解的,但这破解的时间则或长或短。如果key的长度足够长,那么可能穷尽一生,也无法破解特定的数据。或者就算破解了,可能也丧失了数据的时效性。
目前c# wpf自身的函数库就支持数据的加密和解密,对于我们来说能够正常使用就可以了,没有必要过度关注里面的原理部分。
测试的界面不复杂,主要就是准备两个button和两个text。两个button负责加密和解密,而两个text分别表示原文和加密后的报文。
有兴趣的同学可以参考一下这个xaml文件,
前面我们说过,本身c#自带了加密库,所以我们直接引用进来就可以了。
using System.Security.Cryptography;
报文加密与解密,最重要的内容就是密钥的部分。当然,我们这里只是一般的加解密,随意可以用随机数的方法生成密钥。如果是复杂一点的场景,一般使用rsa加解密,即加密的人用公钥来进行数据加密处理,而解密的人则拿着私钥来进行数据解密。
private byte[] Key; // Replace with a secure key
private byte[] IV; // Replace with a secure IV
// generate key
public static byte[] GetRandomKey(int keySize)
{
using (var rng = new RNGCryptoServiceProvider())
{
byte[] key = new byte[keySize / 8]; // Key size is in bits, so convert to bytes
rng.GetBytes(key);
return key;
}
}
// generate IV
public static byte[] GetRandomIV(int blockSize)
{
using (var rng = new RNGCryptoServiceProvider())
{
byte[] iv = new byte[blockSize / 8]; // Block size is in bits, so convert to bytes
rng.GetBytes(iv);
return iv;
}
}
public MainWindow()
{
InitializeComponent();
Key = GetRandomKey(128);
IV = GetRandomIV(128);
}
这里的Key和Iv大家可以看成双密钥去理解就可以了,相当于给一个门安了两把锁。
等密钥弄好之后,就可以开始做数据加密了,相关过程有些拗口,说起来就是首先生成一个Aes对象,接着用Aes对象生成IcryptoTransform,完了之后借助于MemoryStream对象、CryptoStream对象、StreamWriter对象对报文进行加密处理。虽然自己也不知道这个过程是什么意思,但是确实可以实现数据的加密。
// encrypt data
private 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());
}
}
}
数据解密和加密的过程是差不多的,唯一的区别就是在创建ICryptoTransform的时候,调用的是aesAlg.CreateDecryptor,而不是aesAlg.CreateEncryptor。
// decrypt data
private 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();
}
}
}
}
}
测试就更简单了,主要看编译完成之后,验证数据是否可以从原文变成加密文。没问题之后,再看下是不是可以从加密文变成原文。