C# SM2

article/2025/8/20 19:44:32

 Cipher

using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;namespace SM2Test
{/// <summary>/// 密码计算/// </summary>public class Cipher{private int ct = 1;/// <summary>/// 椭圆曲线E上点P2/// </summary>private ECPoint p2;private SM3Digest sm3keybase;private SM3Digest sm3c3;private readonly byte[] key = new byte[32];private byte keyOff = 0;public Cipher(){}private void Reset(){sm3keybase = new SM3Digest();sm3c3 = new SM3Digest();byte[] p;p = p2.Normalize().XCoord.ToBigInteger().ToByteArray();sm3keybase.BlockUpdate(p, 0, p.Length);sm3c3.BlockUpdate(p, 0, p.Length);p = p2.Normalize().YCoord.ToBigInteger().ToByteArray();sm3keybase.BlockUpdate(p, 0, p.Length);ct = 1;NextKey();}private void NextKey(){SM3Digest sm3keycur = new SM3Digest(sm3keybase);sm3keycur.Update((byte)(ct >> 24 & 0x00ff));sm3keycur.Update((byte)(ct >> 16 & 0x00ff));sm3keycur.Update((byte)(ct >> 8 & 0x00ff));sm3keycur.Update((byte)(ct & 0x00ff));sm3keycur.DoFinal(key, 0);keyOff = 0;ct++;}public virtual ECPoint InitEnc(SM2 sm2, ECPoint userKey){AsymmetricCipherKeyPair key = sm2.EccKeyPairGenerator.GenerateKeyPair();ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters)key.Private;ECPublicKeyParameters ecpub = (ECPublicKeyParameters)key.Public;BigInteger k = ecpriv.D;ECPoint c1 = ecpub.Q;p2 = userKey.Multiply(k);Reset();return c1;}public virtual void Encrypt(byte[] data){//p2.Normalize();sm3c3.BlockUpdate(data, 0, data.Length);for (int i = 0; i < data.Length; i++){if (keyOff == key.Length)NextKey();data[i] ^= key[keyOff++];}}public virtual void InitDec(BigInteger userD, ECPoint c1){p2 = c1.Multiply(userD);Reset();}public virtual void Decrypt(byte[] data){for (int i = 0; i < data.Length; i++){if (keyOff == key.Length)NextKey();data[i] ^= key[keyOff++];}sm3c3.BlockUpdate(data, 0, data.Length);}public virtual void Dofinal(byte[] c3){byte[] p = p2.Normalize().YCoord.ToBigInteger().ToByteArray();sm3c3.BlockUpdate(p, 0, p.Length);sm3c3.DoFinal(c3, 0);Reset();}}
}

SM2

using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Security;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace SM2Test
{/// <summary>/// 加密处理中心/// </summary>public class SM2{public static SM2 Instance{get{return new SM2();}}public static SM2 InstanceTest{get{return new SM2();}}#region 曲线参数/// <summary>/// 曲线参数/// </summary>public static readonly string[] CurveParameter = {"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF",// p,0"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC",// a,1"28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93",// b,2"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123",// n,3"32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7",// gx,4"BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0" // gy,5};/// <summary>/// 椭圆曲线参数/// </summary>public string[] EccParam = CurveParameter;/// <summary>/// 椭圆曲线参数P/// </summary>public readonly BigInteger EccP;/// <summary>/// 椭圆曲线参数A/// </summary>public readonly BigInteger EccA;/// <summary>/// 椭圆曲线参数B/// </summary>public readonly BigInteger EccB;/// <summary>/// 椭圆曲线参数N/// </summary>public readonly BigInteger EccN;/// <summary>/// 椭圆曲线参数Gx/// </summary>public readonly BigInteger EccGx;/// <summary>/// 椭圆曲线参数Gy/// </summary>public readonly BigInteger EccGy;#endregion/// <summary>/// 椭圆曲线/// </summary>public readonly ECCurve EccCurve;/// <summary>/// 椭圆曲线的点G/// </summary>public readonly ECPoint EccPointG;/// <summary>/// 椭圆曲线 bc规范/// </summary>public readonly ECDomainParameters EccBcSpec;/// <summary>/// 椭圆曲线密钥对生成器/// </summary>public readonly ECKeyPairGenerator EccKeyPairGenerator;private SM2(){EccParam = CurveParameter;EccP = new BigInteger(EccParam[0], 16);EccA = new BigInteger(EccParam[1], 16);EccB = new BigInteger(EccParam[2], 16);EccN = new BigInteger(EccParam[3], 16);EccGx = new BigInteger(EccParam[4], 16);EccGy = new BigInteger(EccParam[5], 16);ECFieldElement ecc_gx_fieldelement = new FpFieldElement(EccP, EccGx);ECFieldElement ecc_gy_fieldelement = new FpFieldElement(EccP, EccGy);EccCurve = new FpCurve(EccP, EccA, EccB);EccPointG = new FpPoint(EccCurve, ecc_gx_fieldelement, ecc_gy_fieldelement);EccBcSpec = new ECDomainParameters(EccCurve, EccPointG, EccN);ECKeyGenerationParameters ecc_ecgenparam;ecc_ecgenparam = new ECKeyGenerationParameters(EccBcSpec, new SecureRandom());EccKeyPairGenerator = new ECKeyPairGenerator();EccKeyPairGenerator.Init(ecc_ecgenparam);}/// <summary>/// 获取杂凑值H/// </summary>/// <param name="z">Z值</param>/// <param name="data">待签名消息</param>/// <returns></returns>public virtual byte[] Sm2GetH(byte[] z, byte[] data){SM3Digest sm3 = new SM3Digest();//Zsm3.BlockUpdate(z, 0, z.Length);//待签名消息sm3.BlockUpdate(data, 0, data.Length);// Hbyte[] md = new byte[sm3.GetDigestSize()];sm3.DoFinal(md, 0);return md;}/// <summary>/// 获取Z值/// Z=SM3(ENTL∣∣userId∣∣a∣∣b∣∣gx∣∣gy ∣∣x∣∣y) /// </summary>/// <param name="userId">签名方的用户身份标识</param>/// <param name="userKey">签名方公钥</param>/// <returns></returns>public virtual byte[] Sm2GetZ(byte[] userId, ECPoint userKey){SM3Digest sm3 = new SM3Digest();byte[] p;// ENTL由2个字节标识的ID的比特长度 int len = userId.Length * 8;sm3.Update((byte)(len >> 8 & 0x00ff));sm3.Update((byte)(len & 0x00ff));// userId用户身份标识IDsm3.BlockUpdate(userId, 0, userId.Length);// a,b为系统曲线参数;p = EccA.ToByteArray();sm3.BlockUpdate(p, 0, p.Length);p = EccB.ToByteArray();sm3.BlockUpdate(p, 0, p.Length);//  gx、gy为基点p = EccGx.ToByteArray();sm3.BlockUpdate(p, 0, p.Length);p = EccGy.ToByteArray();sm3.BlockUpdate(p, 0, p.Length);// x,y用户的公钥的X和Yp = userKey.Normalize().XCoord.ToBigInteger().ToByteArray();sm3.BlockUpdate(p, 0, p.Length);p = userKey.Normalize().YCoord.ToBigInteger().ToByteArray();sm3.BlockUpdate(p, 0, p.Length);// Zbyte[] md = new byte[sm3.GetDigestSize()];sm3.DoFinal(md, 0);return md;}}}

SM2Utils

using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Utilities.Encoders;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace SM2Test
{class SM2Utils{public static void GenerateKeyPair(out ECPoint publicKey, out BigInteger privateKey){SM2 sm2 = SM2.Instance;AsymmetricCipherKeyPair key = sm2.EccKeyPairGenerator.GenerateKeyPair();ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters)key.Private;ECPublicKeyParameters ecpub = (ECPublicKeyParameters)key.Public;privateKey = ecpriv.D;publicKey = ecpub.Q;}public static String Encrypt(byte[] publicKey, byte[] data){if (null == publicKey || publicKey.Length == 0){return null;}if (data == null || data.Length == 0){return null;}byte[] source = new byte[data.Length];Array.Copy(data, 0, source, 0, data.Length);Cipher cipher = new Cipher();SM2 sm2 = SM2.Instance;ECPoint userKey = sm2.EccCurve.DecodePoint(publicKey);ECPoint c1 = cipher.InitEnc(sm2, userKey);cipher.Encrypt(source);byte[] c3 = new byte[32];cipher.Dofinal(c3);String sc1 = Encoding.Default.GetString(Hex.Encode(c1.GetEncoded()));String sc2 = Encoding.Default.GetString(Hex.Encode(source));String sc3 = Encoding.Default.GetString(Hex.Encode(c3));return (sc1 + sc2 + sc3).ToUpper();}public static byte[] Decrypt(byte[] privateKey, byte[] encryptedData){if (null == privateKey || privateKey.Length == 0){return null;}if (encryptedData == null || encryptedData.Length == 0){return null;}String data = Encoding.Default.GetString(Hex.Encode(encryptedData));byte[] c1Bytes = Hex.Decode(Encoding.Default.GetBytes(data.Substring(0, 130)));int c2Len = encryptedData.Length - 97;byte[] c2 = Hex.Decode(Encoding.Default.GetBytes(data.Substring(130, 2 * c2Len)));byte[] c3 = Hex.Decode(Encoding.Default.GetBytes(data.Substring(130 + 2 * c2Len, 64)));SM2 sm2 = SM2.Instance;BigInteger userD = new BigInteger(1, privateKey);ECPoint c1 = sm2.EccCurve.DecodePoint(c1Bytes);Cipher cipher = new Cipher();cipher.InitDec(userD, c1);cipher.Decrypt(c2);cipher.Dofinal(c3);return c2;}}
}

调用

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Org.BouncyCastle.Utilities.Encoders;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Math;namespace SM2Test
{public partial class Form1 : Form{public Form1(){InitializeComponent();}/// <summary>/// 获取公钥私钥 加密 解密/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void button1_Click(object sender, EventArgs e){ECPoint publicKey=null;BigInteger privateKey=null;SM2Utils.GenerateKeyPair(out publicKey, out privateKey);System.Console.Out.WriteLine("公钥: " + Encoding.Default.GetString(Hex.Encode(publicKey.GetEncoded())).ToUpper());System.Console.Out.WriteLine("私钥: " + Encoding.Default.GetString(Hex.Encode(privateKey.ToByteArray())).ToUpper());String plainText = "lxw测试";byte[] sourceData = Encoding.Default.GetBytes(plainText);//下面的秘钥可以使用generateKeyPair()生成的秘钥内容  //国密规范正式私钥  String prik = "00971C650DB6F5B690C12F6D3651CAD3F6BB2DA9D67F29CA9AF4BAF84A6F2EF5FA";//国密规范正式公钥  String pubk = "047DBFC88D4853D95D9BAD8489C2D77ED6EF012FD80853AA7549CA0857380FD217D323057F551BE49305D1A71AA190767288E3254377CD4970E0DE9CFBA7248E4E";System.Console.Out.WriteLine("加密: ");String cipherText = SM2Utils.Encrypt(Hex.Decode(pubk), sourceData);System.Console.Out.WriteLine(cipherText);System.Console.Out.WriteLine("解密: ");plainText = Encoding.Default.GetString(SM2Utils.Decrypt(Hex.Decode(prik), Hex.Decode(cipherText)));System.Console.Out.WriteLine(plainText);Console.ReadLine();}/// <summary>/// 加密/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void button2_Click(object sender, EventArgs e){String plainText = "lxw测试";String pubk = "047DBFC88D4853D95D9BAD8489C2D77ED6EF012FD80853AA7549CA0857380FD217D323057F551BE49305D1A71AA190767288E3254377CD4970E0DE9CFBA7248E4E";byte[] sourceData = Encoding.Default.GetBytes(plainText);System.Console.Out.WriteLine("加密: ");String cipherText = SM2Utils.Encrypt(Hex.Decode(pubk), sourceData);System.Console.Out.WriteLine(cipherText);System.Console.Out.WriteLine(cipherText.Length);}/// <summary>/// 解密/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void button3_Click(object sender, EventArgs e){String cipherText = "04214B8588CFBADBF06DB82D82FD7FE8BF1C28B583D7646F4D65810F1094B564B5F865BDC8AF6B7BE004ADF46DFFF501520EA3D7C9F161214FFAF8B45AE25C151BFC43B409675FC56FFCAD6A9209525FB694ED00BAB366437A1AA353D48F5FF627DCD9F3041A78EF";//国密规范正式私钥  String prik = "00971C650DB6F5B690C12F6D3651CAD3F6BB2DA9D67F29CA9AF4BAF84A6F2EF5FA";//国密规范正式公钥  String pubk = "047DBFC88D4853D95D9BAD8489C2D77ED6EF012FD80853AA7549CA0857380FD217D323057F551BE49305D1A71AA190767288E3254377CD4970E0DE9CFBA7248E4E";System.Console.Out.WriteLine("解密: ");String plainText = Encoding.Default.GetString(SM2Utils.Decrypt(Hex.Decode(prik), Hex.Decode(cipherText)));System.Console.Out.WriteLine(plainText);}}
}

附件下载


http://chatgpt.dhexx.cn/article/U5vlysjh.shtml

相关文章

Springboot整合SM2加密的笔记

首先要明白公钥是加密&#xff0c;私钥用来解密。 国密公钥格式&#xff1a;公钥为64位&#xff0c;前后各32位&#xff0c;对应椭圆算法中BigInteger X 和 BigInteger X &#xff0c;私钥为32位&#xff0c;对应算法中的BigInteger d。 工具类&#xff1a; 可以参考https:/…

SM2加解密、签名验签

导论 SM2是国家密码管理局于2010年12月17日发布的椭圆曲线公钥密码算法&#xff0c;在我们国家商用密码体系中被用来替换RSA算法。 国产SM2算法&#xff0c;是基于ECC的&#xff0c;但二者在签名验签、加密解密过程中或许有些许区别&#xff0c;目前鄙人还不太清楚&#xff0c…

sm2和sm4加密算法浅析

sm2和sm4加密算法浅析 一: SM2 简介&#xff1a;SM2是国家密码管理局于2010年12月17日发布的椭圆曲线公钥密码算法 &#xff0c;SM2为非对称加密&#xff0c;基于ECC。该算法已公开。由于该算法基于ECC&#xff0c;故其签名速度与秘钥生成速度都快于RSA。ECC 256位&#xff0…

国密算法(SM2)简介及SM2生成秘钥

国密算法&#xff08;SM2&#xff09;生成秘钥 一、国密算法介绍二、SM2算法和RSA算法比较三、生成SM2秘钥1、openssl生成SM2秘钥1.1、安装openssl1.2、生成SM2私钥1.3、生成SM2公钥 2、nodejs:使用sm-crypto包生成SM2秘钥3、c生成秘钥 参考 一、国密算法介绍 国密即国家密码局…

向量积(叉积)

a和b叉积可表示为ab&#xff0c;结果是一个和这两个向量都垂直的伪向量 ab absinθ*n &#xff0c;ab为两向量的模长&#xff0c;θ是两向量的夹角&#xff0c;n是垂直二者的单位向量。 叉积的长度可以理解为以ab为邻边的平行四边形面积 叉积的运算 反交换律 ab-ba 分配律…

向量的点乘(内积)和叉乘(外积)

向量点乘&#xff1a;a * b&#xff08;常被写为a b&#xff09; 点乘,也叫向量的内积、数量积.顾名思义,求下来的结果是一个数. 向量a向量b|a||b|cos 在物理学中,已知力与位移求功,实际上就是求向量F与向量s的内积,即要用点乘. 向量叉乘&#xff1a;a ∧ b&#xff08;常被…

向量的内积(点乘)与外积(叉乘)

向量的内积&#xff08;点乘&#xff09;与外积&#xff08;叉乘&#xff09; 向量的内积点乘 向量的外积叉乘 向量的内积&#xff08;点乘&#xff09; 内积的几何意义&#xff1a; 用来表征或计算两个向量之间的夹角在b向量在a向量方向上的投影。 向量的外积&#xff08;叉…

两向量的向量积

两向量的向量积 两向量 a 与 b 的向量积&#xff08;外积&#xff09;是一个向量&#xff0c;记做 a b \mathbf{a}\times \mathbf{b} ab 或 [ a b ] [\mathbf{a}\mathbf{b}] [ab]&#xff0c;它的模是 ∣ a b ∣ ∣ a ∣ ∣ b ∣ sin ⁡ ∠ ( a , b ) |\mathbf{a}\times…

8.2 向量数量积与向量积(点乘与叉乘)

本篇内容依然是向量的运算&#xff0c;只不过不属于线性运算&#xff0c;内容包括向量的数量积与向量积。 一、向量的数量积&#xff08;内积、点乘&#xff0c;参与运算的是向量&#xff0c;结果是数&#xff09; &#xff08;一&#xff09;问题产生的背景与表达 &#x…

【口诀】巧记泰勒公式

函数 多项式函数 可以计算出精确值 非多项式函数 无法计算出精确值 泰勒公式的本质 多项式函数逼近非多项式函数 随着项数累加&#xff0c;逼近的误差就会越小 规律&#xff1a; 只需要确定x的指数符号只有两种情况 要么符号相同(全为) 要么符号交替( -)开头要么1&am…

matlab泰勒公式含义,泰勒公式的哲学意义与敏捷研发

学过微积分的人都知道泰勒展开公式,它是将一个在x=x0处具有n阶导数的函数f(x)利用关于(x-x0)的n次多项式来逼近函数的方法,用标准的数学术语来描述是这样的:若函数f(x)在包含x0的某个闭区间[a,b]上具有n阶导数,且在开区间(a,b)上具有(n 1)阶导数,则对闭区间[a,b]上任意一点…

泰勒公式及泰勒级数

目录 一、背景二、提出问题三、解决问题四、应用——泰勒级数※ 函数的幂级数展开 参考文献 一、背景 对于一些复杂的函数&#xff0c;通常会找简单的函数做近似&#xff0c;而多项式函数就是常用的一种简单函数。 比如当 ∣ x ∣ |x| ∣x∣ 很小时&#xff0c;有以下近似&a…

泰勒公式求极限(如何用+精度怎么确定)一文扫除泰勒公式难点

有些复杂的极限题&#xff0c;里面会涵盖着各种各样的函数&#xff0c;这些群魔乱舞的函数加大了我们计算极限的难度&#xff0c;此时想&#xff1a;如果可以将这些函数统一成一样的形式该多好?此时&#xff0c;就有我们的泰勒公式了。 1.泰勒公式怎么用&#xff1a; 指数函…

泰勒公式记忆方法

泰勒公式记忆方法 几个常见函数的泰勒公式 f ( x ) f ( x 0 ) f ′ ( x 0 ) ( x − x ) f ′ ′ ( x 0 ) 2 ! ( x − x 0 ) 2 ⋯ f ( n ) ( x 0 ) n ! ( x − x 0 ) n R n ( x ) f ( x ) f ( 0 ) f ′ ( 0 ) x f ′ ′ ( 0 ) 2 ! x 2 ⋯ f ( n ) ( 0 ) n ! x n o (…

理解高斯分布

开始前&#xff0c;先看几个重要概念&#xff1a; 概率函数&#xff1a;把事件概率表示成关于事件变量的函数 概率分布函数&#xff1a;一个随机变量ξ取值小于某一数值x的概率&#xff0c;这概率是x的函数&#xff0c;称这种函数为随机变量ξ的分布函数&#xff0c;简称分布…

透彻理解高斯分布

https://www.toutiao.com/a6639894224189784590/ 2018-12-28 12:22:15 正态分布是与中的定量现象的一个方便模型。各种各样的心理学测试分数和现象比如计数都被发现近似地服从正态分布。 开始前&#xff0c;先看几个重要概念&#xff1a; 概率函数&#xff1a;把事件概率表示成…

高斯分布的一些理解

转自&#xff1a;http://blog.csdn.net/rns521/article/details/6953591 正态分布&#xff08;Normal distribution&#xff09;又名高斯分布&#xff08;Gaussian distribution&#xff09;&#xff0c;是一个在数学、物理及工程等领域都非常重要的概率分布&#xff0c;在统计…

高斯分布拟合

题目&#xff1a; 产生N个服从高斯分布的随机数&#xff0c;计算这些随机数的均值和方差&#xff0c;并与高斯分布的均值和方差比较&#xff0c;N100,1000,10000,100000 import matplotlib.pyplot as plt import scipy.stats as sta import numpy as npmu_True 5 #设置高斯…

高斯分布~

为什么MLE估计服从高斯分布的数据分布方差会估小&#xff1f; 因为MLE求方差是根据数据的均值&#xff0c;并不是分布的期望&#xff0c;因为会根据采样的偏差将均值拉到符合数据的地方&#xff0c;从而算出来的方差会变小。 从几何层面看高维高斯分布 主要看exp上的值&…

机器学习中的高斯分布

高斯分布与数据预处理&#xff1a;数据分布转换高斯分布与聚类&#xff1a;GMM高斯分布与异常检测高斯分布与马氏距离 高斯分布与数据预处理&#xff1a;数据分布转换 当我们上手一个数据集时&#xff0c;往往第一件事就是了解每个特征是如何分布的。特征分布指的就是某个特征在…