package sm2util import ( "encoding/hex" "errors" "math/big" "github.com/tjfoc/gmsm/sm2" ) var ( ErrPrivateKeyIsNil = errors.New("private key is nil") ErrPublicAndKeysNotMatch = errors.New("public and private keys don't match") ) func CheckSm2KeyPair(priv *sm2.PrivateKey, pub *sm2.PublicKey) (pubHex string, err error) { if priv == nil { return "", ErrPrivateKeyIsNil } if pub == nil { pub = &priv.PublicKey return PublicKeyToHex(pub), nil } pubHex = PublicKeyToHex(pub) if pubHex != PublicKeyToHex(&priv.PublicKey) { return "", ErrPublicAndKeysNotMatch } return } /* From: https://github.com/tjfoc/gmsm/issues/207 */ // 国密sm2 非对称加密算法 (对标rsa使用场景) // // ParsePublicKey 公钥字符串还原为 sm2.PublicKey 对象(与java中org.bouncycastle.crypto生成的公私钥完全互通使用) func ParsePublicKey(publicKeyStr string) (*sm2.PublicKey, error) { publicKeyBytes, err := hex.DecodeString(publicKeyStr) if err != nil { return nil, err } // 提取 x 和 y 坐标字节切片 curve := sm2.P256Sm2().Params() byteLen := (curve.BitSize + 7) / 8 xBytes := publicKeyBytes[1 : byteLen+1] yBytes := publicKeyBytes[byteLen+1 : 2*byteLen+1] // 将字节切片转换为大整数 x := new(big.Int).SetBytes(xBytes) y := new(big.Int).SetBytes(yBytes) // 创建 sm2.PublicKey 对象 publicKey := &sm2.PublicKey{ Curve: curve, X: x, Y: y, } return publicKey, nil } // 国密 非对称加密算法 // // ParsePublicKey 公钥字符串还原为 sm2.PublicKey 对象(与java中org.bouncycastle.crypto生成的公私钥完全互通使用) func ParsePublicKeyByXY(xHex, yHex string) (*sm2.PublicKey, error) { xBytes, err := hex.DecodeString(xHex) if err != nil { return nil, err } yBytes, err := hex.DecodeString(yHex) if err != nil { return nil, err } // 提取 x 和 y 坐标字节切片 curve := sm2.P256Sm2().Params() // byteLen := (curve.BitSize + 7) / 8 // 将字节切片转换为大整数 x := new(big.Int).SetBytes(xBytes) y := new(big.Int).SetBytes(yBytes) // 创建 sm2.PublicKey 对象 publicKey := &sm2.PublicKey{ Curve: curve, X: x, Y: y, } return publicKey, nil } func PublicKeyToHex(pk *sm2.PublicKey) (pubKeyString string) { bs := append([]byte{byte(4)}, pk.X.Bytes()...) bs = append(bs, pk.Y.Bytes()...) return hex.EncodeToString(bs) } func PublicKeyToXYHex(pk *sm2.PublicKey) (x, y string) { x = hex.EncodeToString(pk.X.Bytes()) y = hex.EncodeToString(pk.Y.Bytes()) return x, y } // 将私钥字符串反序列化转为私钥对象: // ParsePrivateKey 私钥还原为 sm2.PrivateKey对象(与java中org.bouncycastle.crypto生成的公私钥完全互通使用) func ParsePrivateKey(privateKeyStr string, publicKey *sm2.PublicKey) (*sm2.PrivateKey, error) { privateKeyBytes, err := hex.DecodeString(privateKeyStr) if err != nil { return nil, err } // 将字节切片转换为大整数 d := new(big.Int).SetBytes(privateKeyBytes) // 创建 sm2.PrivateKey 对象 privateKey := &sm2.PrivateKey{ PublicKey: *publicKey, D: d, } return privateKey, nil } func PrivateKeyToHex(pk *sm2.PrivateKey) (d string) { d = hex.EncodeToString(pk.D.Bytes()) return d } /**/