国密 SM2 的非对称签名验签过程

介绍

非对称加密确保了消息传输中的保密性,但是由于使用公钥加密,而公钥是分发出去的,可能泄露,谁都可以使用公钥加密发送消息。

因此为了保证收到的消息是由对应的发送者发出的,就需要用到非对称签名和验签逻辑,发送者通过自己的私钥进行对消息进行签名,

接收方通过公钥对消息进行验证签名。非对称签名还确保了消息在传输过程中未被篡改,还有不可否认性,因为理论上只有发送者才有私钥

椭圆曲线

椭圆曲线和公钥,私钥,和 SM2 的非对称加密解密是一致的,这里再重复提一下。

椭圆曲线是由一组方程描述的点的集合:

y2 = x3 + ax + b 其中 a, b 满足 (4a3 + 27b2 ≠ 0)

SM2 定义了一个 sm2p256v1 的椭圆曲线方程

各种参数

BigInteger p = FromHex("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF");
BigInteger a = FromHex("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC");
BigInteger b = FromHex("28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93");
BigInteger n = FromHex("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123");
BigInteger h = BigInteger.One; Point G coord: (22963146547237050559479531362550074578802567295341616970375194840604139615431, 85132369209828568825618990617112496413088388631904505083283536607588877201568)

公钥,私钥

  • 私钥:

可以随机生成一个 BigInteger d,必须符合区间 [1, n - 1]

  • 公钥:

私钥 d * G(Point) 得到的一个 Point: Q

签名过程

私钥: d

userID: SM2 提供了一个默认的 userId "1234567812345678" 字符串的 byte 数组,可以修改

签名过程主要是为了得到 BigInteger r 和 BigInteger s

摘要过程

  • d * G 生成 公钥点 Q
  • 对 (userID.Length) * 8 >> 8, userID.Length, userID, 方程参数 A, B, 基点G(x,y), 公钥点 Q(x,y), 算出摘要 z
  • 对 z, 原文 算出摘要 eHash: byte[32]
  • 将 eHash 转成 BigInteger e

生成签名

  1. 随机生成一个 BigInteger k
  2. k * G 生成一个 Point(x, y) P
  3. BigInteger r = e + P.x
  4. BigInteger s = (k - r * d) / (d + 1)

发送方将 r,s 编码随着消息发送

验签过程

验签使用公钥点 Q 进行验签 对签名发过来的 BigInteger r, BigInteger s 进行验证

摘要过程

  • 对 (userID.Length) * 8 >> 8, userID.Length, userID, 方程参数 A, B, 基点G(x,y), 公钥点 Q(x,y), 算出摘要 z
  • 对 z, 原文 算出摘要 eHash: byte[32]
  • 将 eHash 转成 BigInteger e
  • 验证等式是否成立: r = e + (s * G + (r + s) * Q).x

证明过程:

已知条件

P = k * G

r = e + P.x

s = (k - r * d) / (d + 1)

公私钥关系 d * G = Q

e + (s * G + (r + s) * Q).x = e + P.x

s * G + (r + s) * Q = P

即要证明 s * G + r * Q + s * Q = k * G

s * G + s * Q + r * Q - k * G

∵ Q = d * G

= s * G + s * d * G + r * d * G - k * G

= (1 + d) * s * G + r * d * G - k * G

∵ s = (k - r * d) / (d + 1)

= (k - r * d) * G + r * d * G - k * G

= k * G - r * d * G + r * d * G - k * G

= k * G - k * G

= 0

总结

  1. 计算过程中省略了对求同余的计算
  2. 加密保证消息传输的保密,加签保证消息是由特定发送者发出,以及消息未被篡改
  3. SM2 算法中,签名过程使用私钥运算生成两个大数 (r, s) 验证过程则使用公钥来确认签名是否有效, 消息是否被篡改
  4. 有的机构在会约定不同的 userID

国密 SM2 的非对称签名验签过程的更多相关文章

  1. 数据安全管理:RSA加密算法,签名验签流程详解

    本文源码:GitHub·点这里 || GitEE·点这里 一.RSA算法简介 1.加密解密 RSA加密是一种非对称加密,在公开密钥加密和电子商业中RSA被广泛使用.可以在不直接传递密钥的情况下,完成加 ...

  2. 谈谈PBOC3.0中使用的国密SM2算法

    转载请注明出处 http://blog.csdn.net/pony_maggie/article/details/39780825 作者:小马 一 知识准备 SM2是国密局推出的一种他们自己说具有自主 ...

  3. 推荐一款能支持国密SM2浏览器——密信浏览器

    密信浏览器( MeSince Browser )是基于Chromium开源项目开发的国密安全浏览器,支持国密算法和国密SSL证书,同时也支持国际算法及全球信任SSL证书:密信浏览器使用界面清新,干净. ...

  4. 利用SHA-1算法和RSA秘钥进行签名验签(带注释)

    背景介绍 1.SHA 安全散列算法SHA (Secure Hash Algorithm)是美国国家标准和技术局发布的国家标准FIPS PUB 180-1,一般称为SHA-1.其对长度不超过264二进制 ...

  5. RSA密钥生成、加密解密、签名验签

    RSA 非对称加密公钥加密,私钥解密 私钥签名,公钥验签 下面是生成随机密钥对: //随机生成密钥对 KeyPairGenerator keyPairGen = null; try { keyPair ...

  6. C# RSACryptoServiceProvider加密解密签名验签和DESCryptoServic

    C#在using System.Security.Cryptography下有 DESCryptoServiceProvider RSACryptoServiceProvider DESCryptoS ...

  7. RSACryptoServiceProvider加密解密签名验签和DESCryptoServiceProvider加解密

    原文:RSACryptoServiceProvider加密解密签名验签和DESCryptoServiceProvider加解密 C#在using System.Security.Cryptograph ...

  8. [Python3] RSA的加解密和签名/验签实现 -- 使用pycrytodome

    Crypto 包介绍: pycrypto,pycrytodome 和 crypto 是一个东西,crypto 在 python 上面的名字是 pycrypto 它是一个第三方库,但是已经停止更新,所以 ...

  9. RSA签名验签

    import android.util.Base64; import java.security.KeyFactory; import java.security.PrivateKey; import ...

  10. js rsa sign使用笔记(加密,解密,签名,验签)

    你将会收获: js如何加密, 解密 js如何签名, 验签 js和Java交互如何相互解密, 验签(重点) 通过谷歌, 发现jsrsasign库使用者较多. 查看api发现这个库功能很健全. 本文使用方 ...

随机推荐

  1. PostgreSQL、KingBase 数据库 ORDER BY LIMIT 查询缓慢案例

    好久没写博客了,最近从人大金仓离职了,新公司入职了蚂蚁集团,正在全力学习 OcenaBase 数据库的体系结构中. 以后分享的案例知识基本上都是以 OcenaBase 分布式数据库为主了,呦西. 昨天 ...

  2. [C++] does not name a type

    从网上找到了以下几点 https://blog.csdn.net/fly20180712/article/details/88306008 1.没有加调用函数的头文件 2.不存在xxx命名空间 3.包 ...

  3. 上来就对标 20k Star 的开源项目,是自不量力还是后起之秀?

    先来一段紧箍咒:nvm.fvm.gvm.sdkman.fnm.n.g.rvm.jenv.phpbrew.rustup.swiftenv.pyenv.rbenv... 这些都是用来解决编程语言多版本管理 ...

  4. springboot,简要记录,方便复习,

    boot 笔记第一步新建工程,导包,由于boot的数据库框架是用mybtis -paus,所以关于数据库系统那儿不用色选mybatis ,需要重新maven导包完整导包以下人容: <?xml v ...

  5. mysql标识列和事务

    1 #标识列 2 /* 3 又称为自增长列 4 含义:可以不用手动的插入值,系统提供默认的序列值 5 6 7 特点: 8 1.标识列必须和主键搭配吗?不一定,但要求是一个key 9 2.一个表可以有几 ...

  6. pip 查看某个包有哪些版本并升级

    查看某个包有哪些版本 pip install xxx== 升级包 pip install xxx==1.1

  7. 简单实用算法——二分查找法(BinarySearch)

    目录 算法概述 适用情况 算法原理 算法实现(C#) 实际应用:用二分查找法找寻边界值 参考文章 算法概述 二分查找(英语:binary search),也叫折半查找(英语:half-interval ...

  8. pod常见的非故障及故障状态解析

    在Kubernetes中,Pod的状态可以反映其当前的生命周期状态.是否正常运行或遇到了某些状况.以下是一些Pod常见的非故障状态: Running:这是Pod最常见的非故障状态,表示Pod已经成功调 ...

  9. 基于python下opuslib的下opus编解码实例解析

    一 opuslib 这个是纯粹的opus封装,要比ogg的那个更底层,ogg的那个封装的太严了.很多业务不方便开展. 二 实例解析: import opuslib import opuslib.api ...

  10. Android Studio导出APP的数据库db文件

    原文地址:Android Studio导出APP的数据库db文件 | Stars-One的杂货小窝 最近项目开发需要使用到Android内置的Sqlite存数据,但是公司里没有对应的调试环境,只能让现 ...