C# SM2 加签、验签工具

news2024/12/30 2:52:50

目录

效果

项目

代码

下载


效果

项目

代码

using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Signers;
using Org.BouncyCastle.Asn1.GM;
using System;
using System.Text;
using System.Windows.Forms;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Utilities.Encoders;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Security;
using System.Linq;

namespace SM2VerifySignTool
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        int toDigit(char ch, int index)
        {
            int digit = Convert.ToInt32(ch.ToString(), 16);
            if (digit == -1)
            {
                throw new SystemException("Illegal hexadecimal character " + ch + " at index " + index);
            }
            return digit;
        }

        string HexToBase64(string hexString)
        {
            byte[] bytes = Enumerable.Range(0, hexString.Length)
                                     .Where(x => x % 2 == 0)
                                     .Select(x => Convert.ToByte(hexString.Substring(x, 2), 16))
                                     .ToArray();
            return Convert.ToBase64String(bytes);
        }

        byte[] hexStrToByte(String hexStr)
        {
            if ((null == hexStr) || (hexStr.Length == 0))
            {
                return null;
            }
            char[] hexData = hexStr.ToCharArray();
            int len = hexData.Length;
            if ((len & 0x1) != 0)
            {
                throw new SystemException("Odd number of characters.");
            }
            byte[] out1 = new byte[len >> 1];

            int i = 0;
            for (int j = 0; j < len; i++)
            {
                int f = toDigit(hexData[j], j) << 4;
                j++;
                f |= toDigit(hexData[j], j);
                j++;
                out1[i] = ((byte)(f & 0xFF));
            }
            return out1;
        }

        X9ECParameters x9ec = GMNamedCurves.GetByName("SM2P256V1");


        /**
        *生成
        */
        void GenerateKey(out string pubkeyStr, out string prikeyStr)
        {
            var g = new ECKeyPairGenerator();
            g.Init(new ECKeyGenerationParameters(new ECDomainParameters(x9ec), new SecureRandom()));
            var k = g.GenerateKeyPair();
            byte[] pubkey = ((ECPublicKeyParameters)k.Public).Q.GetEncoded(false);
            byte[] privkey = ((ECPrivateKeyParameters)k.Private).D.ToByteArray();
            prikeyStr = BitConverter.ToString(privkey).Replace("-", "");
            pubkeyStr = BitConverter.ToString(pubkey).Replace("-", "");
        }

        /**
        *加签
        */
        string Sign(string prikeyStr, string data)
        {
            byte[] msg = Encoding.UTF8.GetBytes(data);
            byte[] priKey = hexStrToByte(prikeyStr);
            SM2Signer sm2Signer = new SM2Signer();
            ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(new BigInteger(1, priKey), new ECDomainParameters(x9ec));

            sm2Signer.Init(true, privateKeyParameters);
            sm2Signer.BlockUpdate(msg, 0, msg.Length);
            return Hex.ToHexString(sm2Signer.GenerateSignature());
        }


        /*
        * 验签
        */
        bool verifySign(string pubkeyStr, string data, string sign)
        {
            byte[] signHex = hexStrToByte(sign);
            byte[] pubkey = hexStrToByte(pubkeyStr);
            byte[] msgByte = Encoding.UTF8.GetBytes(data);
            SM2Signer sm2Signer = new SM2Signer();
            ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters(x9ec.Curve.DecodePoint(pubkey), new ECDomainParameters(x9ec));
            sm2Signer.Init(false, publicKeyParameters);
            sm2Signer.BlockUpdate(msgByte, 0, msgByte.Length);
            return sm2Signer.VerifySignature(signHex);
        }

        private void btnVerify_Click(object sender, EventArgs e)
        {
            txtResult.Text = "";
            try
            {
                string pubk = txtPubkey.Text;
                string data = txtData.Text;
                string sign = txtSign.Text;
                bool b = verifySign(pubk, data, sign);
                if (b)
                {
                    txtResult.Text = "验证成功";
                }
                else
                {
                    txtResult.Text = "验证失败";
                }
            }
            catch (Exception ex)
            {
                txtResult.Text = "验证异常:" + ex.Message;
            }
        }

        /// <summary>
        /// Base64字符串转Hex字符串↓
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                byte[] bytes = Convert.FromBase64String(txtBase64.Text); // 将base64字符串转换为byte数组
                string hexString = BitConverter.ToString(bytes).Replace("-", ""); // 将byte数组转换为Hex字符串
                txtHex.Text = hexString;
            }
            catch (Exception ex)
            {
                txtHex.Text = "转换异常:" + ex.Message;
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //string pubkeyStr = "";
            //string prikeyStr = "";
            //GenerateKey(out pubkeyStr, out prikeyStr);
            //txtPriKey.Text = prikeyStr;
            //txtPubkey.Text = pubkeyStr;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                string prik = txtPriKey.Text;
                string data = txtData.Text;
                txtSign.Text = Sign(prik, data);
            }
            catch (Exception ex)
            {
                txtSign.Text = "加签识别:" + ex.Message;
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            string pubkeyStr = "";
            string prikeyStr = "";
            GenerateKey(out pubkeyStr, out prikeyStr);
            txtPriKey.Text = prikeyStr;
            txtPubkey.Text = pubkeyStr;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            try
            {
                string hexString = txtHex.Text;
                string base64String = HexToBase64(hexString);
                txtBase64.Text = base64String;
            }
            catch (Exception ex)
            {
                txtBase64.Text = "转换异常:" + ex.Message;
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            try
            {
                string originalString = txtStr.Text;
                byte[] bytes = System.Text.Encoding.UTF8.GetBytes(originalString);
                string base64String = Convert.ToBase64String(bytes);
                txtBase64.Text = base64String;
            }
            catch (Exception ex)
            {
                txtBase64.Text = "编码异常:" + ex.Message;
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            try
            {
                string base64String = txtBase64.Text;
                byte[] bytes = Convert.FromBase64String(base64String);
                string decodedString = Encoding.UTF8.GetString(bytes);
                txtStr.Text = decodedString;
            }
            catch (Exception ex)
            {
                txtStr.Text = "解码异常:" + ex.Message;
            }
        }
    }
}
 

using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Signers;
using Org.BouncyCastle.Asn1.GM;
using System;
using System.Text;
using System.Windows.Forms;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Utilities.Encoders;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Security;
using System.Linq;

namespace SM2VerifySignTool
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        int toDigit(char ch, int index)
        {
            int digit = Convert.ToInt32(ch.ToString(), 16);
            if (digit == -1)
            {
                throw new SystemException("Illegal hexadecimal character " + ch + " at index " + index);
            }
            return digit;
        }

        string HexToBase64(string hexString)
        {
            byte[] bytes = Enumerable.Range(0, hexString.Length)
                                     .Where(x => x % 2 == 0)
                                     .Select(x => Convert.ToByte(hexString.Substring(x, 2), 16))
                                     .ToArray();
            return Convert.ToBase64String(bytes);
        }

        byte[] hexStrToByte(String hexStr)
        {
            if ((null == hexStr) || (hexStr.Length == 0))
            {
                return null;
            }
            char[] hexData = hexStr.ToCharArray();
            int len = hexData.Length;
            if ((len & 0x1) != 0)
            {
                throw new SystemException("Odd number of characters.");
            }
            byte[] out1 = new byte[len >> 1];

            int i = 0;
            for (int j = 0; j < len; i++)
            {
                int f = toDigit(hexData[j], j) << 4;
                j++;
                f |= toDigit(hexData[j], j);
                j++;
                out1[i] = ((byte)(f & 0xFF));
            }
            return out1;
        }

        X9ECParameters x9ec = GMNamedCurves.GetByName("SM2P256V1");


        /**
        *生成
        */
        void GenerateKey(out string pubkeyStr, out string prikeyStr)
        {
            var g = new ECKeyPairGenerator();
            g.Init(new ECKeyGenerationParameters(new ECDomainParameters(x9ec), new SecureRandom()));
            var k = g.GenerateKeyPair();
            byte[] pubkey = ((ECPublicKeyParameters)k.Public).Q.GetEncoded(false);
            byte[] privkey = ((ECPrivateKeyParameters)k.Private).D.ToByteArray();
            prikeyStr = BitConverter.ToString(privkey).Replace("-", "");
            pubkeyStr = BitConverter.ToString(pubkey).Replace("-", "");
        }

        /**
        *加签
        */
        string Sign(string prikeyStr, string data)
        {
            byte[] msg = Encoding.UTF8.GetBytes(data);
            byte[] priKey = hexStrToByte(prikeyStr);
            SM2Signer sm2Signer = new SM2Signer();
            ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(new BigInteger(1, priKey), new ECDomainParameters(x9ec));

            sm2Signer.Init(true, privateKeyParameters);
            sm2Signer.BlockUpdate(msg, 0, msg.Length);
            return Hex.ToHexString(sm2Signer.GenerateSignature());
        }


        /*
        * 验签
        */
        bool verifySign(string pubkeyStr, string data, string sign)
        {
            byte[] signHex = hexStrToByte(sign);
            byte[] pubkey = hexStrToByte(pubkeyStr);
            byte[] msgByte = Encoding.UTF8.GetBytes(data);
            SM2Signer sm2Signer = new SM2Signer();
            ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters(x9ec.Curve.DecodePoint(pubkey), new ECDomainParameters(x9ec));
            sm2Signer.Init(false, publicKeyParameters);
            sm2Signer.BlockUpdate(msgByte, 0, msgByte.Length);
            return sm2Signer.VerifySignature(signHex);
        }

        private void btnVerify_Click(object sender, EventArgs e)
        {
            txtResult.Text = "";
            try
            {
                string pubk = txtPubkey.Text;
                string data = txtData.Text;
                string sign = txtSign.Text;
                bool b = verifySign(pubk, data, sign);
                if (b)
                {
                    txtResult.Text = "验证成功";
                }
                else
                {
                    txtResult.Text = "验证失败";
                }
            }
            catch (Exception ex)
            {
                txtResult.Text = "验证异常:" + ex.Message;
            }
        }

        /// <summary>
        /// Base64字符串转Hex字符串↓
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                byte[] bytes = Convert.FromBase64String(txtBase64.Text); // 将base64字符串转换为byte数组
                string hexString = BitConverter.ToString(bytes).Replace("-", ""); // 将byte数组转换为Hex字符串
                txtHex.Text = hexString;
            }
            catch (Exception ex)
            {
                txtHex.Text = "转换异常:" + ex.Message;
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //string pubkeyStr = "";
            //string prikeyStr = "";
            //GenerateKey(out pubkeyStr, out prikeyStr);
            //txtPriKey.Text = prikeyStr;
            //txtPubkey.Text = pubkeyStr;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                string prik = txtPriKey.Text;
                string data = txtData.Text;
                txtSign.Text = Sign(prik, data);
            }
            catch (Exception ex)
            {
                txtSign.Text = "加签识别:" + ex.Message;
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            string pubkeyStr = "";
            string prikeyStr = "";
            GenerateKey(out pubkeyStr, out prikeyStr);
            txtPriKey.Text = prikeyStr;
            txtPubkey.Text = pubkeyStr;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            try
            {
                string hexString = txtHex.Text;
                string base64String = HexToBase64(hexString);
                txtBase64.Text = base64String;
            }
            catch (Exception ex)
            {
                txtBase64.Text = "转换异常:" + ex.Message;
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            try
            {
                string originalString = txtStr.Text;
                byte[] bytes = System.Text.Encoding.UTF8.GetBytes(originalString);
                string base64String = Convert.ToBase64String(bytes);
                txtBase64.Text = base64String;
            }
            catch (Exception ex)
            {
                txtBase64.Text = "编码异常:" + ex.Message;
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            try
            {
                string base64String = txtBase64.Text;
                byte[] bytes = Convert.FromBase64String(base64String);
                string decodedString = Encoding.UTF8.GetString(bytes);
                txtStr.Text = decodedString;
            }
            catch (Exception ex)
            {
                txtStr.Text = "解码异常:" + ex.Message;
            }
        }
    }
}

下载

源码下载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2223782.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

二分查找_在排序数组中查找元素的第一个和最后一个位置

1.朴素二分查找 .二分查找 二分查找思路&#xff1a; 1.left0,rightnums.size()-1&#xff08;最后一个元素下标&#xff09;&#xff0c;取中间元素下标 midleft(right-left)/2 &#xff08;防溢出&#xff09; 2.nums[mid]>target &#xff0c;说明mid右边的元素都大于ta…

软考:缓存和数据库数据一致性问题

参考&#xff1a;CSDN博客&#xff0c;8种方案 前言 为什么要一致 如果数据不一致&#xff0c;那么业务应用从缓存中读取的数据就不是最新的数据&#xff0c;这会导致严重的错误 数据一致性是什么 缓存中有数据&#xff0c;那么&#xff0c;缓存的数据需要和数据库中的值相同 …

vue图片加载失败的图片

1.vue图片加载失败的图片 这个问题发生在测试环境和开发本地&#xff0c;线上环境是可以的&#xff0c;测试环境估计被第三方屏蔽了 2.图片有&#xff0c;却加载不出来 <template v-slot:imageUrlsSlots"{ row }"><div class"flexRow rowCenter"&…

重生之“我打数据结构,真的假的?”--3.栈和队列(无习题)

栈和队列 C语言中的栈和队列总结 在C语言中&#xff0c;**栈&#xff08;Stack&#xff09;和队列&#xff08;Queue&#xff09;**是两种非常重要的数据结构。它们广泛用于各种应用中&#xff0c;比如内存管理、任务调度、表达式求值等。本文将对这两种数据结构进行详细的介…

element ui中el-image组件查看图片的坑

比如说上传组件使用el-image-viewer组件去看&#xff0c;如果用错了&#xff0c;你会发现&#xff0c;你每次只能看一张图片 <template><div><el-upload action"#" list-type"picture-card" :auto-upload"false" :file-list"…

LTSC版本没有微软应用商店怎么办?一招装上

前言 这几天小白在办公电脑上安装了Windows 11 24H2 LTSC版本&#xff0c;哦豁&#xff0c;界面真的清爽。默认桌面上只有一个垃圾桶和EDGE浏览器&#xff0c;就再也没有其他图标了。 &#xff08;吐槽1️⃣&#xff1a;原版系统镜像开机之后不都是这样的吗&#xff1f;这也能…

Rust初踩坑

一、下载 到官网https://www.rust-lang.org/zh-CN/tools/install下载你需要的版本 二、安装 执行rustup-init 文件&#xff0c;选择1 按提示直到安装完成 可以通过以下命令测试&#xff1a; rustc -V # 注意的大写的 V cargo -V # 注意的大写的 V三、在VScode中…

GFF: Gated Fully Fusion for Semantic Segmentation门控融合语义分割-论文阅读笔记

摘要&#xff1a; 语义分割通过对每个像素密集预测其类别&#xff0c;生成对场景的全面理解。深度卷积神经网络的高级特征已经在语义分割任务中证明了它们的有效性&#xff0c;然而高级特征的粗分辨率经常导致对小/薄物体的结果不佳&#xff0c;而这些物体的细节信息非常重要。…

如何在算家云搭建GPT-SOVITS(语音转换)

一、模型介绍 GPT-SOVITS是一款强大的小样本语音转换和文本转语音 WebUI工具。它集成了声音伴奏分离、自动训练集分割、中文ASR和文本标注等辅助工具。 具有以下特征&#xff1a; 零样本 TTS&#xff1a; 输入 5 秒的声音样本并体验即时文本到语音的转换。少量样本 TTS&…

Rust的move关键字在线程中的使用

为什么使用 move&#xff1f; 在 Rust 中&#xff0c;move 关键字主要用于闭包。当我们在一个线程中创建一个闭包并将其传递给另一个线程时&#xff0c;如果闭包中使用了某些变量&#xff0c;就需要决定这些变量的所有权归属。 不使用 move&#xff1a; 默认情况下&#xff0…

python实战项目42:themoviedb电影网站信息

python爬取themoviedb电影网站信息 一、寻找数据接口二、解析主页数据,获取详情页url三、向详情页url发送请求、获取并解析数据四、完整代码一、寻找数据接口 打开网站首页,F12打开开发者工具,刷新页面。 向下滑动页面,点击页面上的“Load More”图标。 寻找到数据接口,…

【网络原理】TCP/IP五层网络模型之网络层-----IP协议详解,建议收藏!!

&#x1f490;个人主页&#xff1a;初晴~ &#x1f4da;相关专栏&#xff1a;计算机网络那些事 前几篇文章中我们深入研究了TCP协议&#xff0c;因为TCP协议在我们日常开发中的使用频率非常高。而相比之下&#xff0c;IP协议与我们普通程序员关系就没那么近了。一般是专门开发…

2024年妈杯MathorCup大数据竞赛A题超详细解题思路

2024年妈杯大数据竞赛初赛整体难度约为0.6个国赛。A题为台风中心路径相关问题&#xff0c;为评价预测问题&#xff1b;B题为库存和销量的预测优化问题。B题难度稍大于A题&#xff0c;可以根据自己队伍情况进行选择。26日早六点之前发布AB两题相关解题代码论文。 下面为大家带来…

创建型模式-----建造者模式

目录 背景&#xff1a; 构建模式UML 代码示例 房子成品&#xff1a; 构建器抽象&#xff1a; 具体构建器&#xff1a; 建筑师&#xff1a; 测试部…

配置nginx服务通过ip访问多网站

1.关闭防火墙 [rootlocalhost wzj]# systemctl stop firewalld [rootlocalhost wzj]# sstenforce 0 bash: sstenforce: command not found... [rootlocalhost wzj]# setenforce 0 2&#xff0c;挂mnt [rootlocalhost wzj]# mount/dev/sr0/mnt bash: mount/dev/sr0/mnt: No suc…

C++20中头文件ranges的使用

<ranges>是C20中新增加的头文件&#xff0c;提供了一组与范围(ranges)相关的功能&#xff0c;此头文件是ranges库的一部分。包括&#xff1a; 1.concepts: (1).std::ranges::range:指定类型为range&#xff0c;即它提供开始迭代器和结束标记(it provides a begin iterato…

【WPF】中Dispatcher的DispatcherPriority参数使用

在 WPF 中&#xff0c;DispatcherPriority 参数用于指定通过 Dispatcher 调度的操作的执行优先级。加入 DispatcherPriority 参数的情况通常取决于你希望操作何时以及如何被执行。 1.Dispatcher的DispatcherPriority参数使用 以下是几种情况和示例说明&#xff1a; 1.1 需要…

量子纠错--shor‘s 码

定理1 (量子纠错的条件) C是一组量子编码&#xff0c;P是映射到C上的投影算子。假设是一个算子元素描述的量子操作&#xff0c;那么基于量子编码C&#xff0c;存在一个能对抗描述的噪声的纠错操作R的充要条件是 对某个复元素厄米矩阵成立。 将算子元素称为导致的错误。如果这样…

数字 图像处理算法的形式

一 基本功能形式 按图像处理的输出形式&#xff0c;图像处理的基本功能可分为三种形式。 1&#xff09;单幅图像 单幅图像 2&#xff09;多幅图像 单幅图像 3&#xff09;单&#xff08;或多&#xff09;幅图像 数字或符号等 二 几种具体算法形式 1.局部处理邻域对于任一…

第二单元历年真题整理

1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 参考答案 1. A 2. A 3. A 4. D 5. D 6. D 解析&#xff1a; 栈和队列是两个不一样的结构&#xff0c;不能放在一起表示 7. B 8. C 解析&#xff1a; S --> A0 | B1 --> (S1 | 1) 0 | (S0 | 0)1 --> S10 | 10 | S…