bdcontract-client/sdk-go/sm2util/util.go

124 lines
3.2 KiB
Go
Raw Permalink Normal View History

2024-11-26 10:54:32 +00:00
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
}
/**/