124 lines
3.2 KiB
Go
124 lines
3.2 KiB
Go
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
|
||
}
|
||
|
||
/**/
|