C# WPF上位机开发(加密和解密)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱: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 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大家可以看成双密钥去理解就可以了,相当于给一个门安了两把锁。

4、数据加密

        等密钥弄好之后,就可以开始做数据加密了,相关过程有些拗口,说起来就是首先生成一个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());
                }
            }
        }

5、数据解密

        数据解密和加密的过程是差不多的,唯一的区别就是在创建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();
                        }
                    }
                }
            }
        }

6、软件测试

        测试就更简单了,主要看编译完成之后,验证数据是否可以从原文变成加密文。没问题之后,再看下是不是可以从加密文变成原文。

Guess you like

Origin blog.csdn.net/feixiaoxing/article/details/135028381