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