前段时间将系统的RSA算法全部升级为SM2国密算法,密码机和UKey硬件设备大都同时支持RSA和SM2算法,只是应用系统的加解密签名验证需要修改,这个更改底层调用的加密动态库来,原来RSA用的对称加密算法DES(AES)和摘要MD5(SHA1)也相应改变,分别对应SM1、SM3算法,SM1算法基于硬件实现,SM2、SM3算法已公开。

SM2签名验证算法

SM2签名同样也是需要先摘要原文数据,即先使用SM3密码杂凑算法计算出32byte摘要。SM3需要摘要签名方ID(默认1234567812345678)、曲线参数a,b,Gx,Gy、共钥坐标(x,y)计算出Z值,然后再杂凑原文得出摘要数据。这个地方要注意曲线参数和坐标点都是32byte,在转换为BigInteger大数计算转成字节流时要去掉空补位,否则可能会出现摘要计算不正确的问题。SM2签名实现如下:

public static BigInteger[] Sm2Sign(byte[] md, AsymmetricCipherKeyPair keypair)

{

SM3Digest sm3 = new SM3Digest();

ECPublicKeyParameters ecpub = (ECPublicKeyParameters)keypair.Public;

byte[] z = SM2CryptoServiceProvider.Sm2GetZ(Encoding.Default.GetBytes(SM2CryptoServiceProvider.userId), ecpub.Q);

sm3.BlockUpdate(z, 0, z.Length);

byte[] p = md;

sm3.BlockUpdate(p, 0, p.Length);

byte[] hashData = new byte[32];

sm3.DoFinal(hashData, 0);

// e

BigInteger e = new BigInteger(1, hashData);

// k

BigInteger k = null;

ECPoint kp = null;

BigInteger r = null;

BigInteger s = null;

BigInteger userD = null;

do

{

do

{

ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters)keypair.Private;

k = ecpriv.D;

kp = ecpub.Q;

userD = ecpriv.D;

// r

r = e.Add(kp.X.ToBigInteger());

r = r.Mod(ecc_n);

}

while (r.Equals(BigInteger.Zero) || r.Add(k).Equals(ecc_n));

// (1 + dA)~-1

BigInteger da_1 = userD.Add(BigInteger.One);

da_1 = da_1.ModInverse(ecc_n);

// s

s = r.Multiply(userD);

s = k.Subtract(s).Mod(ecc_n);

s = da_1.Multiply(s).Mod(ecc_n);

}

while (s.Equals(BigInteger.Zero));

byte[] btRS = new byte[64];

byte[] btR = r.ToByteArray();

byte[] btS = s.ToByteArray();

Array.Copy(btR, btR.Length - 32, btRS, 0, 32);

Array.Copy(btS, btS.Length - 32, btRS, 32, 32);

return new BigInteger[] { r, s };

}

SM2算法是基于ECC算法的,签名同样返回2个大数,共64byte。由于原来RSA算法已很普遍支持,要实现RSA的签名验签都有标准库的实现,而SM2是国密算法在国际上还没有标准通用,算法Oid标识在X509标准中是没定义的。在.Net或Java中可以基于使用BouncyCastle加密库实现,开源的也比较好学习扩展。SM2算法验签可以使用软验签,即可以不需要使用硬件设备,同样使用原始数据、签名、证书(公钥)来实现对签名方验证,保证数据完整性未被篡改。验证过程同样需先摘要原文数据,公钥在证书中是以一个66byte的BitString,去掉前面标记位即64byte为共钥坐标(x,y),中间分割截取再以Hex方式转成BigInteger大数计算,验签代码如下:

public static bool Verify(byte[] msg, byte[] signData, byte[] certData)

{

X509Certificate2 x5092 = new X509Certificate2(certData);

byte[] certPK = x5092.GetPublicKey();

certPK = SubByte(certPK, 1, 64);

byte[] certPKX = SubByte(certPK, certPK.Length - 32 - 32, 32);

byte[] certPKY = SubByte(certPK, certPK.Length - 32, 32);

System.String strcertPKX = ByteToHexStr(certPKX);

System.String strcertPKY = ByteToHexStr(certPKY);

BigInteger biX = new BigInteger(strcertPKX, 16);

BigInteger biY = new BigInteger(strcertPKY, 16);

ECFieldElement x = new FpFieldElement(ecc_p, biX);

ECFieldElement y = new FpFieldElement(ecc_p, biY);

ECPoint userKey = new FpPoint(ecc_curve, x, y);

SM3Digest sm3 = new SM3Digest();

byte[] z = Sm2GetZ(Encoding.Default.GetBytes(userId), userKey);

sm3.BlockUpdate(z, 0, z.Length);

byte[] p = msg;

sm3.BlockUpdate(p, 0, p.Length);

byte[] md = new byte[32];

sm3.DoFinal(md, 0);

byte[] btR = SubByte(signData, 0, 32);

byte[] btS = SubByte(signData, 32, 32);

System.String strR = ByteToHexStr(btR);

System.String strS = ByteToHexStr(btS);

BigInteger r = new BigInteger(strR, 16);

BigInteger s = new BigInteger(strS, 16);

// e_

BigInteger e = new BigInteger(1, md);

// t

BigInteger t = r.Add(s).Mod(ecc_n);

if (t.Equals(BigInteger.Zero))

return false;

// x1y1

ECPoint x1y1 = ecc_point_g.Multiply(s);

x1y1 = x1y1.Add(userKey.Multiply(t));

// R

BigInteger R = e.Add(x1y1.X.ToBigInteger()).Mod(ecc_n);

return r.Equals(R);

}

制作SM2证书

基于BouncyCastle开源库,可以轻松制作X509证书、CRL、pkcs10、pkcs12,支持国际通用的RSA、ECC算法。制作SM2证书可以通过扩展BouncyCastle库来实现,需加入SM2签名算法DerObjectIdentifier标识1.2.156.10197.1.501(基于SM3的SM2算法签名),密钥对的生成使用国密推荐曲线参数,然后如上所示自行实现SM2签名验证算法。X509证书由证书主体、证书签名算法标识、签名组成,和RSA证书主要不同的是SM2证书的签名算法标识和签名,及证书公钥使用ECKeyParameters。生成自签名SM2证书代码如下:

SM2证书生成

public static Org.BouncyCastle.X509.X509Certificate MakeRootCert(string filePath, IDictionary subjectNames)

{

AsymmetricCipherKeyPair keypair = SM2CryptoServiceProvider.SM2KeyPairGenerator.GenerateKeyPair();

ECPublicKeyParameters pubKey = (ECPublicKeyParameters)keypair.Public; //CA公钥

ECPrivateKeyParameters priKey = (ECPrivateKeyParameters)keypair.Private;    //CA私钥

X509Name issuerDN = new X509Name(GetDictionaryKeys(subjectNames), subjectNames);

X509Name subjectDN = issuerDN;  //自签证书,两者一样

SM2X509V3CertificateGenerator sm2CertGen = new SM2X509V3CertificateGenerator();

//X509V3CertificateGenerator sm2CertGen = new X509V3CertificateGenerator();

sm2CertGen.SetSerialNumber(new BigInteger(128, new Random()));   //128位

sm2CertGen.SetIssuerDN(issuerDN);

sm2CertGen.SetNotBefore(DateTime.UtcNow.AddDays(-1));

sm2CertGen.SetNotAfter(DateTime.UtcNow.AddDays(365 * 10));

sm2CertGen.SetSubjectDN(subjectDN);

sm2CertGen.SetPublicKey(pubKey); //公钥

sm2CertGen.SetSignatureAlgorithm("SM3WITHSM2");

sm2CertGen.AddExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(true));

sm2CertGen.AddExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(pubKey));

sm2CertGen.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(pubKey));

sm2CertGen.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(6));

Org.BouncyCastle.X509.X509Certificate sm2Cert = sm2CertGen.Generate(keypair);

sm2Cert.CheckValidity();

sm2Cert.Verify(pubKey);

return sm2Cert;

}

X509证书使用ASN1语法进行编码,是用类型标识、长度和值序列来描述数据结构的。SM2证书在制作设置公钥时,默认会带ECKeyParameters参数,并没有SM2的公钥参数1.2.156.10197.1.301,因此需要自己写个SM2椭圆曲线密码算法标识对象,这样在生成的证书中就可以看到公钥参数字段,如下所示:

SM2证书公钥标识

using System;

using Org.BouncyCastle.Asn1.X509;

using Org.BouncyCastle.Asn1;

namespace Common.Security

{

public class SM2AlgorithmIdentifier

: AlgorithmIdentifier

{

private readonly bool parametersDefined;

public SM2AlgorithmIdentifier(

DerObjectIdentifier objectID):base(objectID)

{

}

public SM2AlgorithmIdentifier(

DerObjectIdentifier    objectID,

Asn1Encodable parameters)

: base(objectID, parameters)

{

this.parametersDefined = true;

}

/**

* Produce an object suitable for an Asn1OutputStream.

*          *      AlgorithmIdentifier ::= Sequence {

*                            algorithm OBJECT IDENTIFIER,

*                            parameters ANY DEFINED BY algorithm OPTIONAL }

*

*/

public override Asn1Object ToAsn1Object()

{

DerObjectIdentifier sm2Identifier = new DerObjectIdentifier("1.2.156.10197.1.301");

Asn1EncodableVector v = new Asn1EncodableVector(base.ObjectID, sm2Identifier);

return new DerSequence(v);

}

}

}

SM2算法是国密局公布的公钥密码算法,在相当强度下密钥比RSA短,在使用智能卡有限空间存储时非常可贵。目前国内很多CA大都升级支持SM2算法证书,相信以后会慢慢地推广更多应用,也期望之后能与国际标准接轨。

附:

国密推荐256位曲线参数

p=FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFF

a=FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFC

b=28E9FA9E 9D9F5E34 4D5A9E4B CF6509A7 F39789F5 15AB8F92 DDBCBD41 4D940E93

n=FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF 7203DF6B 21C6052B 53BBF409 39D54123

Gx=32C4AE2C 1F198119 5F990446 6A39C994 8FE30BBF F2660BE1 715A4589 334C74C7

Gy=BC3736A2 F4F6779C 59BDCEE3 6B692153 D0A9877C C62A4740 02DF32E5 2139F0A0

ec java sm2证书_国密算法SM2证书制作相关推荐

  1. 国密算法java源码_国密算法SM2证书制作

    前段时间将系统的RSA算法全部升级为SM2国密算法,密码机和UKey硬件设备大都同时支持RSA和SM2算法,只是应用系统的加解密签名验证需要修改,这个更改底层调用的加密动态库来,原来RSA用的对称加密 ...

  2. 国密算法SM2证书制作

    原文链接:http://www.jonllen.com/jonllen/work/162.aspx 国密算法SM2证书制作 分类:工作 大中小 前段时间将系统的RSA算法全部升级为SM2国密算法,密码 ...

  3. 国密算法SM2加解密_签名验签图形化例子

    点击上方蓝字可直接关注!方便下次阅读.如果对你有帮助,麻烦点个在看或点个赞,感谢~ 国密SM2概述 对国密算法有了解的朋友看到SM2可能会先想到非对称加密,之前的SM4是对称加密.SM4加解密使用的是 ...

  4. 国密算法—SM2介绍及基于BC的实现

    国密算法-SM2介绍及基于BC的实现 文章目录 国密算法-SM2介绍及基于BC的实现 简介 私钥 公钥 数据格式 密钥数据格式 私钥数据格式 公钥数据格式 加密数据格式 签名数据格式 计算过程 生成密 ...

  5. 基于国密算法SM2SSL证书的https加密,如何实现?

    为什么80%的码农都做不了架构师?>>>    如果要在客户端/网关系统和服务端之间进行SSL加密通信,当客户端应用(浏览器等)发起登录认证.加密.签名等请求时,服务端如何实现基于国 ...

  6. 国密算法(SM2,SM3,SM4)完善与算法辅助工具开发

    国密算法SM2,SM3和改名发布的SM4的应用好像越来越多了.首先是国密SM2证书的升级,国内CA服务商要完成SM2算法证书支持,之后是国密算法在金融领域进行推广,新近编订的PBOC标准的增强安全部分 ...

  7. 国密算法 SM2 SM3 SM4 及密钥生成

    国密算法 SM2 SM3 SM4 方式一:SM2密钥在线生成 SM2密钥在线生成工具 如果你没线下生成工具,可用下面2种线上生成方式之一: 1. sm2密钥在线生成(const.net.cn) 2.  ...

  8. 主流CA吊销俄罗斯数字证书启示:升级国密算法SSL证书,助力我国网络安全自主可控

    随着国际和民间黑客组织的加入,俄乌的战争快速蔓延成一场全球化的网络信息战.国际上主流CA机构不再为俄罗斯提供数字证书服务,甚至吊销俄罗斯相关的一些国家基础设施网站的证书.这让俄罗斯不得不开始建立国家C ...

  9. 国密算法 SM2公钥密码 SM3杂凑算法 SM4分组密码 python代码完整实现

    包含SM2公钥密码.SM3杂凑算法和SM4分组密码的国密算法完整工具包完成了.此前分别发布过上述三个算法的代码: SM2:国密算法 SM2 公钥加密 非对称加密 数字签名 密钥协商 python实现完 ...

最新文章

  1. 1-1 机器学习和深度学习综述-paddle
  2. POJ3111 K Best —— 01分数规划 二分法
  3. 中兴高达和中兴啥关系_41家通信传输设备公司研发投入排名:中兴通讯、烽火通信最敢投...
  4. php 7.2 兼容5.5吗,PHP5.5至PHP7.2 新特性整理
  5. Buildroot构建指南——工具链
  6. 链接服务器 慢_redis服务器cpu100%的原因和解决方案
  7. 3.过滤——相关滤波(Correlation Filtering)_3
  8. 解决BLOB/TEXT column can‘t have a default value query问题
  9. 大数据发展火爆,云计算平台主打安全至上
  10. Ubuntu 20.04安装搜狗输入法(图文详解)
  11. java验证手机号格式
  12. Linux笔记7-系统管理
  13. 飞思卡尔imx6q交叉编译工具有关问题
  14. Java中的控制(耦合)反转
  15. vip163邮箱手机版登陆入口是哪个?vip邮箱163实用技巧
  16. 计算机大赛应用文档制作,PPT制作应用大赛策划书
  17. Python解包技巧
  18. win10如何让窗口固定保持在最上层
  19. MySQL基础|设置登录用户权限,访问ip地址---防止数据库误删,详细版
  20. tensorflow 常遇函数

热门文章

  1. 等势线matlab仿真
  2. 2022,又一批AI大牛从大厂出走了
  3. thymeleaf模板引擎的优势何在?
  4. 第一节:服务注册与服务发现
  5. 计算机存储周期越长运算速度,计算机组成原理作业答案
  6. Dilworth定理
  7. redis3.0.7 cluster 集群部署
  8. win 7系统(64位)安装包
  9. 调节睡眠周期(有助睡眠)
  10. 动作识别阅读笔记(三)《Temporal Segment Networks: Towards Good Practices for Deep Action Recognition》