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
版权归原作者 bug的搬运工 所有, 如有侵权,请联系我们删除。