基于C#实现SM2加签验签工具

 更新时间:2024年10月21日 10:21:02   作者:天天代码码天天  
这篇文章主要为大家详细介绍了如何基于C#实现一个SM2加签验签工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

效果

项目

代码

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;
            }
        }
    }
}

到此这篇关于基于C#实现SM2加签验签工具的文章就介绍到这了,更多相关C#SM2加签验签内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • c#中oracle的to_date函数使用方法

    c#中oracle的to_date函数使用方法

    C#使用参数传值方式操作oracle的date字段,主要介绍了oracle的to_date使用方法,大家参考使用吧
    2014-01-01
  • C#设计模式之ChainOfResponsibility职责链模式解决真假美猴王问题实例

    C#设计模式之ChainOfResponsibility职责链模式解决真假美猴王问题实例

    这篇文章主要介绍了C#设计模式之ChainOfResponsibility职责链模式解决真假美猴王问题,简单说明了责任链模式的概念,并结合《西游记》中真假美猴王故事背景为实例分析了责任链模式的具体使用技巧,需要的朋友可以参考下
    2017-09-09
  • C#姓名脱敏的几种实现方法

    C#姓名脱敏的几种实现方法

    在C#中实现姓名脱敏,主要通过字符串处理来隐藏部分信息,保护用户隐私,下面就来详细的介绍一下几种实现方法,感兴趣的可以了解一下
    2025-11-11
  • C#中设置textbox限制条件的方法

    C#中设置textbox限制条件的方法

    这篇文章主要介绍了C#中设置textbox限制条件的方法,可实现设置像数量、价格、金额等的textbox的限制条件,用户只能输入数字或小数,是非常实用的技巧,需要的朋友可以参考下
    2014-12-12
  • c#委托学习示例分享

    c#委托学习示例分享

    委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性,下面是c#委托示例
    2014-03-03
  • C# Hook钩子实例代码 截取键盘输入

    C# Hook钩子实例代码 截取键盘输入

    C# Hook钩子实例代码之截取键盘输入,需要的朋友可以参考下
    2013-05-05
  • ListView Adapter优化 实例

    ListView Adapter优化 实例

    ListView Adapter优化 实例,需要的朋友可以参考一下
    2013-04-04
  • C# Memcached缓存用法实例详解

    C# Memcached缓存用法实例详解

    这篇文章主要介绍了C#中Memcached缓存用法,以实例形式详细讲述了在C#中针对Memcached缓存的各种操作,非常具有实用价值,需要的朋友可以参考下
    2014-10-10
  • C#中Task异步的常用方法

    C#中Task异步的常用方法

    Task是微软极力推荐的一种多线程处理方式,在线程的延续、取消,以及多个线程的等待处理等方面要优于Thread,ThreadPool,以下介绍的是Task的常用方法,需要的朋友可以参考下
    2025-07-07
  • C#操作Clipboard读取剪切板中数据实例详解

    C#操作Clipboard读取剪切板中数据实例详解

    这篇文章主要介绍了C#操作Clipboard读取剪切板中数据的方法,实例分析了C#读取剪贴板数据的具体步骤与实现技巧,需要的朋友可以参考下
    2015-05-05

最新评论