bdcontract-client/sm2util/util.go
2024-11-29 17:57:52 +08:00

124 lines
3.2 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}
/**/