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


    国密 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
  • 相关阅读:
    如何防止网站被爬虫爬取的几种办法
    JMM与JUC
    CMake Cookbook
    1459_TC275_Lite_Kit-UserManual阅读笔记1
    开源DMS文档管理系统 Nuxeo Vs Alfresco对比及 API 使用概述
    leetcode - 1980. Find Unique Binary String
    uboot引导vxworks--t4080调试记录
    logback--进阶--05--自定义Appenders
    JVM学习五
    Request和Response介绍 [Tomcat][Servlet]
  • 原文地址:https://www.cnblogs.com/huiyuanai709/p/18132266/sm2_sign_verify