Winform窗体 SM4加解密

本文介绍了如何在.NETFramework项目中使用SM4和DES进行加密和解密操作,展示了加密解密的代码片段,以及SM4的128位秘钥和CBC模式的使用。DES加密结果显示为乱码,提示可能的编码问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  在程序检测中,由于不允许密码以明文的形式出现。所以需要加密存储,再解密使用。这里使用SM4和DES来制作一个案例,故制作了一个dome实现简单的加解密。

一、实验准备

1、创建Winform项目(我这里依赖.net framework)

2、NuGet包引入国密包(点击安装即可,我这里选择上面的一个)

(右击项目引用 -> 选择管理NuGet程序包 -> 点击左上角浏览,输入KYSharp.SM点击安装即可)

3、DES是System.Security.Cryptography包下的类,如果需要使用其他加密方式,DES 类 (System.Security.Cryptography) | Microsoft Learn是官网连接。

二、案例实现

1、代码展示(只需提取加密解密方法即可)

using KYSharp.SM;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        private string password;
        //秘钥
        private string key = "Gt@3k&g8";
        //初始化向量
        private string iv = "25dH%7K5";

        private string SM4key = "Gt@3k&g8Gt@3k&g8";
        //初始化向量
        private string SM4iv = "25dH%7K525dH%7K5";

        private int type = 1;

        private SM4Utils sM4 = new SM4Utils();
        public Form1()
        {
            InitializeComponent();
        }

        //加密
        private void button2_Click(object sender, EventArgs e)
        {
            //DES加密
            if (1 == type)
            {
                //byte[] keyByte = Encoding.UTF8.GetBytes(key);
                byte[] keyByte = UnicodeEncoding.Unicode.GetBytes(key);
                byte[] ivByte = UnicodeEncoding.Unicode.GetBytes(iv);
                byte[] passwordByte = UnicodeEncoding.Unicode.GetBytes(password);

                using(DESCryptoServiceProvider dESCryptoServiceProvider = new DESCryptoServiceProvider())
                {
                    Array.Resize(ref keyByte, 8);
                    Array.Resize(ref ivByte, 8);
                    dESCryptoServiceProvider.Key = keyByte;
                    dESCryptoServiceProvider.IV = ivByte;

                    ICryptoTransform transform = dESCryptoServiceProvider.CreateEncryptor();
                    byte[] paaswordEncodeByte = transform.TransformFinalBlock(passwordByte, 0, passwordByte.Length);
                    label4.Text = UnicodeEncoding.Unicode.GetString(paaswordEncodeByte);
                }
            }
            else
            {
                if (sM4.secretKey == null||"".Equals(sM4.secretKey))
                {
                    sM4.secretKey = SM4key;
                    sM4.iv = SM4iv;
                }
                string sM4PasswordEncodeStr = sM4.Encrypt_CBC(password);
                label4.Text = sM4PasswordEncodeStr;
            }
        }

        //解密
        private void button3_Click(object sender, EventArgs e)
        {
            if (1 == type)
            {
                //byte[] keyByte = Encoding.UTF8.GetBytes(key);
                byte[] keyByte = UnicodeEncoding.Unicode.GetBytes(key);
                byte[] ivByte = UnicodeEncoding.Unicode.GetBytes(iv);
                byte[] passwordByte = UnicodeEncoding.Unicode.GetBytes(label4.Text);

                using (DESCryptoServiceProvider dESCryptoServiceProvider = new DESCryptoServiceProvider())
                {
                    Array.Resize(ref keyByte, 8);
                    Array.Resize(ref ivByte, 8);
                    dESCryptoServiceProvider.Key = keyByte;
                    dESCryptoServiceProvider.IV = ivByte;

                    ICryptoTransform transform = dESCryptoServiceProvider.CreateDecryptor();
                    byte[] paaswordEncodeByte = transform.TransformFinalBlock(passwordByte, 0, passwordByte.Length);
                    label5.Text = UnicodeEncoding.Unicode.GetString(paaswordEncodeByte);
                }
            }
            else
            {
                if (sM4.secretKey == null || "".Equals(sM4.secretKey))
                {
                    sM4.secretKey = SM4key;
                    sM4.iv = SM4iv;
                }
                string sM4PasswordDecodeStr = sM4.Decrypt_CBC(label4.Text);
                label5.Text = sM4PasswordDecodeStr;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (type == 1)
            {
                this.type = 2;
                label4.Text = "加密密码";
                label5.Text = "解密密码";
                label2.Text = "SM4";
            }
            else
            {
                this.type = 1;
                label5.Text = "解密密码";
                label4.Text = "加密密码";
                label2.Text = "DES";
            }
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            this.password = textBox1.Text;
        }
    }
}

2、结果展示

SM4结果展示

DES结果展示

3、SM4的秘钥(代码中SM4key)是128位(16字节),偏移量(即随机数,一般随机生成)和秘钥相同。秘钥和偏移量均可大小写字母、数字和特殊字符组成。SM4有两种模式(CBC、DCB),我这里选择CBC模式。

三、总结

 1、由于时间有限,并没有过多研究加解密。在案例中使用的是对称加密的方式,在国内SM4是不错的选择。

2、案例中DES加密,虽然能够成功加解密,但加密后输出的是乱码文字(可能是使用Unicode编码造成,没有过多研究)。

3、案例中秘钥和偏移量是设置固定值,也可以随机生成。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值