国密 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. 为什么(++a)+(++a)=14

    目录 概述 验证 反编译大法 Java 测试 概述 今天有学妹问我,下面这个代码为啥结果是14 int a=5; printf("%d\n",(++a)+(++a)); 我一看,第 ...

  2. Netty笔记(3) - 核心组件

    各组件关系示意图: Bootstrap 和 ServerBootstrap 说明: Bootstrap 意思是引导,一个 Netty 应用通常由一个 Bootstrap 开始,主要作用是配置整个 Ne ...

  3. idea技巧-自定义后缀补全

    Idea技巧-Postfix Completion 在idea中可以使用.xxx进行后缀补全 比如.sout 如何自定义后缀补全? 比如.log 在idea中打开设置 File | Settings ...

  4. 如何避免MYSQL主从延迟带来的读写问题?

    在MYSQL 部署架构选型上,许多公司都会用到主从读写分离的架构,如下是一个一主一从的架构,主库master负责写入,从库slave进行读取. 但是既然是读写分离,必然会面临这样一个问题,当在主库上进 ...

  5. be动词 系动词 连缀动词 Linking Verb

    be动词 系动词 连缀动词 Linking Verb be 原型 am 第一人称单数形式 is 第三人称单数形式 are 第二人称单数和复数形式 been 过去分词 being 现在分词 was 第一 ...

  6. [SCOI 2009] 迷路 (矩阵快速幂)

    [SCOI 2009]迷路 传送门 问题描述 Windy 在有向图中迷路了. 该有向图有 \({N}\) 个节点,Windy 从节点 \({1}\) 出发,他必须恰好在 \({T}\) 时刻到达节点 ...

  7. 基于stm32H730的解决方案开发之SD卡的读写调试

    一 概述 在嵌入式小系统领域,SD卡存储是一个非常重要的功能.可从难度上,它又是非常难的.因为它涉及到两个大的功能点,一个是文件系统,这个难度非一般.另外一个是sd卡的底层驱动.涉及到的接口多,所以也 ...

  8. Vue2和ElementUI编写的无限级菜单路由

    Vue2和ElementUI编写的无限级菜单路由 文章转载自:www.javaman.cn <template> <div> <el-menu :default-acti ...

  9. Kotlin学习快速入门(12)—— 位运算符

    由于不懂pythod,最近拜托朋友研究下解密live2d模型的解密算法,朋友写出了Java的代码 之后我进行改版,在转为kotlin的时候,发现kotlin自动转换有些坑,以及kotlin中的位运算符 ...

  10. OBS无法捕获 chrome、webkit、electron窗口,捕获后黑屏

    使用 electron 打包的 pc 应用,用于直播软件推流的 OBS 捕获窗体黑屏 现象:唯独chrome浏览器 edge 浏览器等,其它窗体都正常. 猜测:是由 chromium 内核引起的 修改 ...