0


golang使用SM2(SM2withSM3)签名、验签数据

golang使用SM2签名、验签数据

场景

对接招行支付

标准

密钥

私钥:Hex格式,SM2标准秘钥格式,私钥为32字节字节流,转换为HEX格式为64字节
公钥:base64格式,并且符合ANS1标准,base64编码后总长度为124字节
SM2标准公钥头:3059301306072A8648CE3D020106082A811CCF5501822D03420004

签名算法

数字签名采用SM2withSM3签名算法,签名方式为PKCS#1裸签名,签名USER_ID使用国密局推荐ID,即“1234567812345678”,使用国密私钥对签名字符串进行加签,生成签名值。

Start

依赖

import("crypto/rand""encoding/base64""encoding/hex""fmt""github.com/ZZMarquis/gm/sm2""strings")

公钥转base64

func PubToBase64(pub *sm2.PublicKey) string {
    pub.GetRawBytes()bytes:= pub.X.Bytes()
    bytes =append(bytes, pub.Y.Bytes()...)pubHex:="3059301306072a8648ce3d020106082a811ccf5501822d03420004"+ hex.EncodeToString(bytes)
    decode,_:= hex.DecodeString(pubHex)base64Pub:= base64.StdEncoding.EncodeToString(decode)return base64Pub
}

私钥转hex

func PriToHex(pri *sm2.PrivateKey) string {hex:= hex.EncodeToString(pri.GetRawBytes())return hex
}

私钥生成公钥

func PriToBase64Pub(pri *sm2.PrivateKey) string {pub:= sm2.CalculatePubKey(pri)base64Pub:=PubToBase64(pub)return base64Pub
}

生成密钥对

func Generate()(string, string){
    pri, pub,_:= sm2.GenerateKey(rand.Reader)returnPriToHex(pri),PubToBase64(pub)}

Hex私钥转私钥对象

func HexToPri(priStr string)*sm2.PrivateKey {// 解码hex私钥
    privateKeyByte,_:= hex.DecodeString(priStr)// 转成go版的私钥
    pri,err:= sm2.RawBytesToPrivateKey(privateKeyByte)if err != nil {panic("私钥加载异常")}return pri
}

base64公钥转公钥对象

func Base64ToPub(pubStr string)*sm2.PublicKey {
    decode,_:= base64.StdEncoding.DecodeString(pubStr)pubHex:= hex.EncodeToString(decode)
    pubHex = strings.ReplaceAll(pubHex,"3059301306072a8648ce3d020106082a811ccf5501822d03420004","")
    pubByte,_:= hex.DecodeString(pubHex)
    pub,_:= sm2.RawBytesToPublicKey(pubByte)return pub
}

签名

func Sign(data string, pri *sm2.PrivateKey) string {
    signature,err:= sm2.Sign(pri,[]byte("1234567812345678"),[]byte(data))if err != nil {panic("云闪付签名错误")}// 转 base64sign:= base64.StdEncoding.EncodeToString(signature)return sign
}

验签

func Verify(data, sign string, pub *sm2.PublicKey) bool {
    sign1,_:= base64.StdEncoding.DecodeString(sign)return sm2.Verify(pub,[]byte("1234567812345678"),[]byte(data), sign1)}

测试

func Test(){//生成密钥对
    hexPri,basePub:=Generate()println("******* 生成 hex私钥:"+ hexPri)println("******* 生成 base公钥:"+ basePub)//Hex私钥转私钥对象pri:=HexToPri(hexPri)//base64公钥转公钥对象pub:=Base64ToPub(basePub)//私钥生成公钥base64Pub:=PriToBase64Pub(pri)println("******* 私钥生成base64公钥:"+ base64Pub)//私钥转hexpriHex:=PriToHex(pri)println("******* 私钥转hex:"+ priHex)//公钥转base64pubBase:=PubToBase64(pub)println("******* 公钥转base64:"+ pubBase)//签名sign:=Sign("abc=123", pri)println("******* 签名:"+ sign)//验签ver:=Verify("abc=123", sign, pub)println(fmt.Sprintf("******* 验签:%t", ver))}
******* 生成 hex私钥:ad606a552feb3b46b2ad47eab8491da7a97d796385b01149aac1e3e5c53f876a
******* 生成 base公钥:MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEJhdEFCw7pKnAR9mPZYKCkntiz+A1HRX5rDP1a2lYQjxXY2zLm4PoYm9hdlayBkGx/kzr/EIeapsxJa5Y+fAxMg==******* 私钥生成base64公钥:MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEJhdEFCw7pKnAR9mPZYKCkntiz+A1HRX5rDP1a2lYQjxXY2zLm4PoYm9hdlayBkGx/kzr/EIeapsxJa5Y+fAxMg==******* 私钥转hex:ad606a552feb3b46b2ad47eab8491da7a97d796385b01149aac1e3e5c53f876a
******* 公钥转base64:MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEJhdEFCw7pKnAR9mPZYKCkntiz+A1HRX5rDP1a2lYQjxXY2zLm4PoYm9hdlayBkGx/kzr/EIeapsxJa5Y+fAxMg==******* 签名:MEQCIEn0F0EUVWGNvH7bMiveXNHFzOCVZkT+X4Y9zI9AL/HLAiAMScSwJs/8ZEf2QLw4ThYYqWvgAG+A0Lj3bq+ljvww6Q==******* 验签:true
标签: golang

本文转载自: https://blog.csdn.net/weixin_42704356/article/details/129669531
版权归原作者 bug的搬运工 所有, 如有侵权,请联系我们删除。

“golang使用SM2(SM2withSM3)签名、验签数据”的评论:

还没有评论