SM2算法加密解密

该代码段展示了如何使用BouncyCastle库在.NET环境中实现SM2加密和解密操作。DXTEST类包含了加密、解密方法,以及初始化公钥和私钥的逻辑。加密过程包括时间戳拼接、SM2加密、Base64编码和URL编码,而解密则进行相反的步骤。
摘要由CSDN通过智能技术生成

using Org.BouncyCastle.Asn1.GM;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Signers;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities.Encoders;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace KFNets.Cool.BLL.Users.STDX
{
    public class DXTEST
    {
        //实例化
        public static string sm2()
        {

            string pukey = "";//公钥
            string PRKEY = "";

            var handle = new DXTEST(pukey, PRKEY, DXTEST.Mode.C1C3C2);
            //加密
            var ts = GetTimeStamp(DateTime.Now);// 时间戳
            string str ="";//时间戳+openid
            //sm2加密
            var Encryptdata = handle.Encrypt(System.Text.Encoding.UTF8.GetBytes(str));
            string datac = Hex.ToHexString(Encryptdata);
            datac = "";//应用IP+SM2加密数据
            //BASE64  加密
            System.Text.Encoding encoding = System.Text.Encoding.GetEncoding("UTF-8");
            byte[] buffer = encoding.GetBytes(datac);
            datac = Convert.ToBase64String(buffer, Base64FormattingOptions.None);

            var aa = System.Web.HttpUtility.UrlEncode(datac);

            string result = System.Web.HttpUtility.UrlDecode(aa);
            return result;
        }
        public static string GetTimeStamp(System.DateTime time)
        {
            long ts = ConvertDateTimeToInt(time);
            return ts.ToString();
        }
        public static long ConvertDateTimeToInt(System.DateTime time)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0));
            long t = (time.Ticks - startTime.Ticks) / 10000;  //除10000调整为13位  
            return t;
        }
        public DXTEST(string pubkey, string privkey, Mode mode = Mode.C1C2C3, bool isPkcs8 = false)
            {
                if (pubkey != null)
                    this.pubkey = pubkey;
                if (privkey != null)
                    this.privkey = privkey;
                this.mode = mode;
            }
        string pubkey;
        string privkey;
        Mode mode;

            ICipherParameters _privateKeyParameters;
            ICipherParameters PrivateKeyParameters
            {
                get
                {
                    try
                    {
                        var r = _privateKeyParameters;
                        if (r == null) r = _privateKeyParameters =
                                new ECPrivateKeyParameters(new BigInteger(privkey, 16),
                                new ECDomainParameters(GMNamedCurves.GetByName("SM2P256V1")));
                        return r;
                    }
                    catch (Exception ex)
                    {
                        return null;
                    }
                }
            }

            ICipherParameters _publicKeyParameters;
            ICipherParameters PublicKeyParameters
            {
                get
                {
                    try
                    {
                        var r = _publicKeyParameters;
                        if (r == null)
                        {
                            //截取64字节有效的SM2公钥(如果公钥首个字节为0x04)
                            if (pubkey.Length > 128)
                            {
                                pubkey = pubkey.Substring(pubkey.Length - 128);
                            }
                            //将公钥拆分为x,y分量(各32字节)
                            String stringX = pubkey.Substring(0, 64);
                            String stringY = pubkey.Substring(stringX.Length);
                            //将公钥x、y分量转换为BigInteger类型
                            BigInteger x = new BigInteger(stringX, 16);
                            BigInteger y = new BigInteger(stringY, 16);
                            //通过公钥x、y分量创建椭圆曲线公钥规范
                            var x9ec = GMNamedCurves.GetByName("SM2P256V1");
                            r = _publicKeyParameters = new ECPublicKeyParameters(x9ec.Curve.CreatePoint(x, y),
                                new ECDomainParameters(x9ec));
                        }
                        return r;
                    }
                    catch (Exception ex)
                    {
                        return null;
                        ;
                    }
                }
            }

            public byte[] Decrypt(byte[] data)
            {
                try
                {
                    if (mode == Mode.C1C3C2)
                        data = C132ToC123(data);
                    var sm2 = new SM2Engine();
                    sm2.Init(false, this.PrivateKeyParameters);
                    return sm2.ProcessBlock(data, 0, data.Length);
                }
                catch (Exception ex)
                {
                    return null;
                }
            }
            public byte[] Encrypt(byte[] data)
            {
                try
                {
                    //  var sm2 = new SM2Engine(new SM3Digest());
                    var sm2 = new SM2Engine();
                    sm2.Init(true, new ParametersWithRandom(this.PublicKeyParameters));
                    data = sm2.ProcessBlock(data, 0, data.Length);
                    if (mode == Mode.C1C3C2)
                        data = C123ToC132(data);
                    return data;
                }
                catch (Exception ex)
                {
                    return null;
                }
            }

            static byte[] C123ToC132(byte[] c1c2c3)
            {
                var gn = GMNamedCurves.GetByName("SM2P256V1");
                int c1Len = (gn.Curve.FieldSize + 7) / 8 * 2 + 1;
                int c3Len = 32;
                byte[] result = new byte[c1c2c3.Length];
                Array.Copy(c1c2c3, 0, result, 0, c1Len); //c1
                Array.Copy(c1c2c3, c1c2c3.Length - c3Len, result, c1Len, c3Len); //c3
                Array.Copy(c1c2c3, c1Len, result, c1Len + c3Len, c1c2c3.Length - c1Len - c3Len); //c2
                return result;

            }
            static byte[] C132ToC123(byte[] c1c3c2)
            {
                var gn = GMNamedCurves.GetByName("SM2P256V1");
                int c1Len = (gn.Curve.FieldSize + 7) / 8 * 2 + 1;
                int c3Len = 32;
                byte[] result = new byte[c1c3c2.Length];
                Array.Copy(c1c3c2, 0, result, 0, c1Len); //c1: 0->65
                Array.Copy(c1c3c2, c1Len + c3Len, result, c1Len, c1c3c2.Length - c1Len - c3Len); //c2
                Array.Copy(c1c3c2, c1Len, result, c1c3c2.Length - c3Len, c3Len); //c3
                return result;

            }
            public enum Mode
            {
                C1C2C3, C1C3C2
            }
    }
}
 

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值