refactor: 重构trustlog-sdk目录结构到trustlog/go-trustlog

- 将所有trustlog-sdk文件移动到trustlog/go-trustlog/目录
- 更新README中所有import路径从trustlog-sdk改为go-trustlog
- 更新cookiecutter配置文件中的项目名称
- 更新根目录.lefthook.yml以引用新位置的配置
- 添加go.sum文件到版本控制
- 删除过时的示例文件

这次重构与trustlog-server保持一致的目录结构,
为未来支持多语言SDK(Python、Java等)预留空间。
This commit is contained in:
ryan
2025-12-22 13:37:57 +08:00
commit d313449c5c
87 changed files with 20622 additions and 0 deletions

393
api/model/signature.go Normal file
View File

@@ -0,0 +1,393 @@
package model
import (
"crypto/rand"
"errors"
"fmt"
"github.com/crpt/go-crpt"
_ "github.com/crpt/go-crpt/sm2" // Import SM2 to register it
"go.yandata.net/iod/iod/trustlog-sdk/api/logger"
)
var (
ErrPrivateKeyIsNil = errors.New("private key is nil")
ErrPublicAndKeysNotMatch = errors.New("public and private keys don't match")
)
// ComputeSignature 计算SM2签名.
// 这是 SDK 默认的签名函数,使用 SM2 算法(内部自动使用 SM3 哈希)。
//
// 参数:
// - data: 待签名的原始数据
// - privateKeyDER: 私钥的DER编码字节数组
//
// 返回: 签名字节数组.
// 注意: go-crpt 库会自动使用 SM3 算法计算摘要并签名。
func ComputeSignature(data, privateKeyDER []byte) ([]byte, error) {
log := logger.GetGlobalLogger()
log.Debug("Computing SM2 signature",
"dataLength", len(data),
"privateKeyDERLength", len(privateKeyDER),
)
if len(privateKeyDER) == 0 {
log.Error("Private key is empty")
return nil, errors.New("private key cannot be empty")
}
if len(data) == 0 {
log.Error("Data to sign is empty")
return nil, errors.New("data to sign cannot be empty")
}
// 解析DER格式的私钥
log.Debug("Parsing SM2 private key from DER format")
privateKey, err := crpt.PrivateKeyFromBytes(crpt.SM2, privateKeyDER)
if err != nil {
log.Error("Failed to parse SM2 private key",
"error", err,
"keyLength", len(privateKeyDER),
)
return nil, fmt.Errorf("failed to parse SM2 private key (key length: %d): %w", len(privateKeyDER), err)
}
if privateKey == nil {
log.Error("Parsed private key is nil")
return nil, ErrPrivateKeyIsNil
}
// 使用SM2签名ASN.1编码go-crpt 库会自动使用 SM3 计算摘要
log.Debug("Signing raw data with SM2 using ASN.1 encoding (SM3 hash)")
signature, err := crpt.SignMessage(privateKey, data, rand.Reader, nil)
if err != nil {
log.Error("Failed to sign data with SM2",
"error", err,
"dataLength", len(data),
)
return nil, fmt.Errorf("failed to sign data with SM2 (data length: %d): %w", len(data), err)
}
log.Debug("SM2 signature computed successfully",
"dataLength", len(data),
"signatureLength", len(signature),
)
return signature, nil
}
// VerifySignature 验证SM2签名.
// 这是 SDK 默认的验签函数,使用 SM2 算法(内部自动使用 SM3 哈希)。
//
// 参数:
// - data: 原始数据
// - publicKeyDER: 公钥的DER编码字节数组
// - signature: 签名字节数组
//
// 返回: 验证是否成功和可能的错误.
// 注意: go-crpt 库会自动使用 SM3 算法计算摘要并验证。
func VerifySignature(data, publicKeyDER, signature []byte) (bool, error) {
log := logger.GetGlobalLogger()
log.Debug("Verifying SM2 signature",
"dataLength", len(data),
"publicKeyDERLength", len(publicKeyDER),
"signatureLength", len(signature),
)
if len(publicKeyDER) == 0 {
log.Error("Public key is empty")
return false, errors.New("public key cannot be empty")
}
if len(data) == 0 {
log.Error("Data to verify is empty")
return false, errors.New("data to verify cannot be empty")
}
if len(signature) == 0 {
log.Error("Signature is empty")
return false, errors.New("signature cannot be empty")
}
// 解析DER格式的公钥,复用ParseSM2PublicDER以避免代码重复
log.Debug("Parsing SM2 public key from DER format")
publicKey, err := ParseSM2PublicDER(publicKeyDER)
if err != nil {
log.Error("Failed to parse SM2 public key",
"error", err,
"keyLength", len(publicKeyDER),
)
return false, fmt.Errorf("failed to parse SM2 public key (key length: %d): %w", len(publicKeyDER), err)
}
// 验证签名ASN.1编码go-crpt 库会自动使用 SM3 计算摘要
log.Debug("Verifying signature with SM2 using ASN.1 encoding (SM3 hash)")
ok, err := crpt.VerifyMessage(publicKey, data, crpt.Signature(signature), nil)
if err != nil {
log.Error("Failed to verify SM2 signature",
"error", err,
"dataLength", len(data),
"signatureLength", len(signature),
)
return false, fmt.Errorf("failed to verify signature: %w", err)
}
if !ok {
log.Warn("SM2 signature verification failed",
"dataLength", len(data),
"signatureLength", len(signature),
)
return false, fmt.Errorf(
"signature verification failed (data length: %d, signature length: %d)",
len(data), len(signature),
)
}
log.Debug("SM2 signature verified successfully",
"dataLength", len(data),
)
return true, nil
}
// GenerateSM2KeyPair 生成SM2密钥对.
// 这是 SDK 默认推荐的密钥生成方法。
//
// 返回新生成的密钥对,包含公钥和私钥.
// SM2 算法会在签名时自动使用 SM3 哈希。
func GenerateSM2KeyPair() (*SM2KeyPair, error) {
log := logger.GetGlobalLogger()
log.Debug("Generating SM2 key pair")
pub, priv, err := crpt.GenerateKey(crpt.SM2, rand.Reader)
if err != nil {
log.Error("Failed to generate SM2 key pair", "error", err)
return nil, fmt.Errorf("failed to generate SM2 key pair: %w", err)
}
if priv == nil {
log.Error("Generated private key is nil")
return nil, errors.New("generated private key is nil")
}
log.Debug("SM2 key pair generated successfully")
return &SM2KeyPair{
Public: pub,
Private: priv,
}, nil
}
// SM2KeyPair SM2密钥对,包含公钥和私钥.
type SM2KeyPair struct {
Public crpt.PublicKey `json:"publicKey"`
Private crpt.PrivateKey `json:"privateKey"`
}
// MarshalSM2PrivateDER 将私钥编码为DER格式.
// 将SM2私钥转换为DER格式的字节数组,用于存储或传输.
func MarshalSM2PrivateDER(priv crpt.PrivateKey) ([]byte, error) {
log := logger.GetGlobalLogger()
log.Debug("Marshaling SM2 private key to DER format")
if priv == nil {
log.Error("Private key is nil")
return nil, errors.New("private key is nil")
}
der := priv.Bytes()
log.Debug("SM2 private key marshaled to DER successfully",
"derLength", len(der),
)
return der, nil
}
// ParseSM2PrivateDER 从DER格式解析私钥.
// 将DER格式的字节数组解析为SM2私钥对象.
func ParseSM2PrivateDER(der []byte) (crpt.PrivateKey, error) {
log := logger.GetGlobalLogger()
log.Debug("Parsing SM2 private key from DER format",
"derLength", len(der),
)
if len(der) == 0 {
log.Error("DER encoded private key is empty")
return nil, errors.New("DER encoded private key cannot be empty")
}
key, err := crpt.PrivateKeyFromBytes(crpt.SM2, der)
if err != nil {
log.Error("Failed to parse SM2 private key from DER",
"error", err,
"derLength", len(der),
)
return nil, fmt.Errorf("failed to parse SM2 private key from DER (length: %d): %w", len(der), err)
}
log.Debug("SM2 private key parsed from DER successfully")
return key, nil
}
// MarshalSM2PublicDER 将公钥编码为DER格式.
// 将SM2公钥转换为DER格式的字节数组,用于存储或传输.
func MarshalSM2PublicDER(pub crpt.PublicKey) ([]byte, error) {
log := logger.GetGlobalLogger()
log.Debug("Marshaling SM2 public key to DER format")
if pub == nil {
log.Error("Public key is nil")
return nil, errors.New("public key is nil")
}
der := pub.Bytes()
log.Debug("SM2 public key marshaled to DER successfully",
"derLength", len(der),
)
return der, nil
}
// ParseSM2PublicDER 从DER格式解析公钥.
// 将DER格式的字节数组解析为SM2公钥对象.
// 返回解析后的公钥,如果数据不是有效的SM2公钥则返回错误.
func ParseSM2PublicDER(der []byte) (crpt.PublicKey, error) {
log := logger.GetGlobalLogger()
log.Debug("Parsing SM2 public key from DER format",
"derLength", len(der),
)
if len(der) == 0 {
log.Error("DER encoded public key is empty")
return nil, errors.New("DER encoded public key cannot be empty")
}
publicKey, err := crpt.PublicKeyFromBytes(crpt.SM2, der)
if err != nil {
log.Error("Failed to parse SM2 public key",
"error", err,
"derLength", len(der),
)
return nil, fmt.Errorf("failed to parse SM2 public key (DER length: %d): %w", len(der), err)
}
log.Debug("SM2 public key parsed from DER successfully")
return publicKey, nil
}
// SignMessage 使用密钥对签名消息标准SM2签名.
// 使用标准SM2算法对消息进行签名,不包含用户标识(uid).
func (kp *SM2KeyPair) SignMessage(msg []byte) ([]byte, error) {
log := logger.GetGlobalLogger()
log.Debug("Signing message with SM2 key pair",
"messageLength", len(msg),
)
if kp.Private == nil {
log.Error("Private key is nil")
return nil, ErrPrivateKeyIsNil
}
signature, err := crpt.SignMessage(kp.Private, msg, rand.Reader, nil)
if err != nil {
log.Error("Failed to sign message with SM2",
"error", err,
"messageLength", len(msg),
)
return nil, err
}
log.Debug("Message signed successfully with SM2",
"messageLength", len(msg),
"signatureLength", len(signature),
)
return signature, nil
}
// SignGM 使用密钥对签名消息国密标准SM2签名,带uid.
// 使用符合GB/T 32918标准的SM2算法对消息进行签名,包含用户标识(uid).
// uid用于Z值计算,通常为用户ID或标识符.
func (kp *SM2KeyPair) SignGM(msg, uid []byte) ([]byte, error) {
log := logger.GetGlobalLogger()
log.Debug("Signing message with SM2 GM standard",
"messageLength", len(msg),
"uidLength", len(uid),
)
if kp.Private == nil {
log.Error("Private key is nil")
return nil, ErrPrivateKeyIsNil
}
// go-crpt uses SM3 hash internally, pass nil for standard signing
signature, err := crpt.SignMessage(kp.Private, msg, rand.Reader, nil)
if err != nil {
log.Error("Failed to sign message with SM2 GM standard",
"error", err,
"messageLength", len(msg),
)
return nil, err
}
log.Debug("Message signed successfully with SM2 GM standard",
"messageLength", len(msg),
"signatureLength", len(signature),
)
return signature, nil
}
// VerifyMessage 使用公钥验证签名标准SM2验签.
// 验证标准SM2签名,不使用用户标识(uid).
// 返回验证结果和可能的错误.如果验证失败但没有错误发生,返回(false, nil).
func (kp *SM2KeyPair) VerifyMessage(msg, sig []byte) (bool, error) {
log := logger.GetGlobalLogger()
log.Debug("Verifying message signature with SM2",
"messageLength", len(msg),
"signatureLength", len(sig),
)
if kp.Public == nil {
log.Error("Public key is nil")
return false, ErrPublicAndKeysNotMatch
}
ok, err := crpt.VerifyMessage(kp.Public, msg, crpt.Signature(sig), nil)
if err != nil {
log.Error("Error verifying message with SM2",
"error", err,
"messageLength", len(msg),
)
return false, err
}
if ok {
log.Debug("Message signature verified successfully with SM2",
"messageLength", len(msg),
)
} else {
log.Warn("Message signature verification failed with SM2",
"messageLength", len(msg),
"signatureLength", len(sig),
)
}
return ok, nil
}
// VerifyGM 使用公钥验证签名国密标准SM2验签,带uid.
// 验证符合GB/T 32918标准的SM2签名,使用用户标识(uid).
// 返回验证结果和可能的错误.如果验证失败但没有错误发生,返回(false, nil).
func (kp *SM2KeyPair) VerifyGM(msg, sig, uid []byte) (bool, error) {
log := logger.GetGlobalLogger()
log.Debug("Verifying message signature with SM2 GM standard",
"messageLength", len(msg),
"signatureLength", len(sig),
"uidLength", len(uid),
)
if kp.Public == nil {
log.Error("Public key is nil")
return false, ErrPublicAndKeysNotMatch
}
// go-crpt uses SM3 hash internally
ok, err := crpt.VerifyMessage(kp.Public, msg, crpt.Signature(sig), nil)
if err != nil {
log.Error("Error verifying message with SM2 GM standard",
"error", err,
"messageLength", len(msg),
)
return false, err
}
if ok {
log.Debug("Message signature verified successfully with SM2 GM standard",
"messageLength", len(msg),
)
} else {
log.Warn("Message signature verification failed with SM2 GM standard",
"messageLength", len(msg),
"signatureLength", len(sig),
)
}
return ok, nil
}