• 国密 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
  • 相关阅读:
    为什么建议你多吃黄瓜,这7大健康益处你需要知道
    vue如何动态加载显示本地图片资源
    JAVA:实现Matrix Graphs矩阵图算法(附完整源码)
    目标检测—YOLO系列(二 ) 全面解读复现YOLOv1 PyTorch
    红杉官网已删长文:伴随SBF一路走来的救世主情结(上)
    89:第七章:开发前台首页、作家个人展示页、粉丝等功能:10:【前台,作家中心:粉丝比例柱状图、饼状图;粉丝地域分布】(前端图表使用Echarts实现;)
    Apache Common CLI 使用方法
    【AUTOSAR-Nm】-2.1-APP SWC如何获取CanNm/LinNm...状态机的跳转
    CRM与销售能力自动化SFA的关系
    [附源码]计算机毕业设计springboot第三方游戏零售平台
  • 原文地址:https://www.cnblogs.com/huiyuanai709/p/18132266/sm2_sign_verify