Files
go-trustlog/api/model/config_signer.go
ryan d313449c5c 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等)预留空间。
2025-12-22 13:37:57 +08:00

208 lines
5.6 KiB
Go
Raw 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 model
import (
"fmt"
"github.com/crpt/go-crpt"
_ "github.com/crpt/go-crpt/ed25519" // 注册 Ed25519
_ "github.com/crpt/go-crpt/sm2" // 注册 SM2
"go.yandata.net/iod/iod/trustlog-sdk/api/logger"
)
// ConfigSigner 基于配置的通用签名器
// 根据 CryptoConfig 自动使用对应的签名算法
type ConfigSigner struct {
privateKey []byte // 私钥(序列化格式)
publicKey []byte // 公钥(序列化格式)
config *CryptoConfig // 密码学配置
privKey crpt.PrivateKey // 解析后的私钥
pubKey crpt.PublicKey // 解析后的公钥
}
// NewConfigSigner 创建基于配置的签名器
// 如果 config 为 nil则使用全局配置
func NewConfigSigner(privateKey, publicKey []byte, config *CryptoConfig) (*ConfigSigner, error) {
if config == nil {
config = GetGlobalCryptoConfig()
}
log := logger.GetGlobalLogger()
log.Debug("Creating ConfigSigner",
"algorithm", config.SignatureAlgorithm,
"privateKeyLength", len(privateKey),
"publicKeyLength", len(publicKey),
)
signer := &ConfigSigner{
privateKey: privateKey,
publicKey: publicKey,
config: config,
}
// 延迟解析密钥,只在需要时解析
// 这样可以避免初始化顺序问题
log.Debug("ConfigSigner created successfully",
"algorithm", config.SignatureAlgorithm,
)
return signer, nil
}
// NewDefaultSigner 创建使用默认 SM2 算法的签名器
// 注意:总是使用 SM2不受全局配置影响
func NewDefaultSigner(privateKey, publicKey []byte) (*ConfigSigner, error) {
sm2Config := &CryptoConfig{
SignatureAlgorithm: SM2Algorithm,
}
return NewConfigSigner(privateKey, publicKey, sm2Config)
}
// Sign 对数据进行签名
func (s *ConfigSigner) Sign(data []byte) ([]byte, error) {
if len(s.privateKey) == 0 {
return nil, fmt.Errorf("private key is not set")
}
log := logger.GetGlobalLogger()
log.Debug("Signing with ConfigSigner",
"algorithm", s.config.SignatureAlgorithm,
"dataLength", len(data),
)
// 根据算法类型使用对应的方法
switch s.config.SignatureAlgorithm {
case SM2Algorithm:
// SM2 使用现有的 ComputeSignature 函数(兼容 DER 格式)
signature, err := ComputeSignature(data, s.privateKey)
if err != nil {
log.Error("Failed to sign with SM2",
"error", err,
)
return nil, err
}
log.Debug("Signed successfully with SM2",
"signatureLength", len(signature),
)
return signature, nil
default:
// 其他算法使用 crpt 通用接口
// 懒加载:解析私钥
if s.privKey == nil {
keyType, err := s.config.SignatureAlgorithm.toKeyType()
if err != nil {
return nil, err
}
privKey, err := crpt.PrivateKeyFromBytes(keyType, s.privateKey)
if err != nil {
log.Error("Failed to parse private key",
"algorithm", s.config.SignatureAlgorithm,
"error", err,
)
return nil, fmt.Errorf("failed to parse private key: %w", err)
}
s.privKey = privKey
}
signature, err := crpt.SignMessage(s.privKey, data, nil, nil)
if err != nil {
log.Error("Failed to sign with ConfigSigner",
"algorithm", s.config.SignatureAlgorithm,
"error", err,
)
return nil, fmt.Errorf("failed to sign: %w", err)
}
log.Debug("Signed successfully with ConfigSigner",
"algorithm", s.config.SignatureAlgorithm,
"signatureLength", len(signature),
)
return signature, nil
}
}
// Verify 验证签名
func (s *ConfigSigner) Verify(data, signature []byte) (bool, error) {
if len(s.publicKey) == 0 {
return false, fmt.Errorf("public key is not set")
}
log := logger.GetGlobalLogger()
log.Debug("Verifying with ConfigSigner",
"algorithm", s.config.SignatureAlgorithm,
"dataLength", len(data),
"signatureLength", len(signature),
)
// 根据算法类型使用对应的方法
switch s.config.SignatureAlgorithm {
case SM2Algorithm:
// SM2 使用现有的 VerifySignature 函数(兼容 DER 格式)
ok, err := VerifySignature(data, s.publicKey, signature)
if err != nil {
// VerifySignature 在验证失败时也返回错误,需要判断错误类型
// 如果是 "signature verification failed",则返回 (false, nil)
if ok == false {
// 验证失败(不是异常)
log.Warn("Verification failed with SM2")
return false, nil
}
// 其他错误(如解析错误)
log.Error("Failed to verify with SM2", "error", err)
return false, err
}
log.Debug("Verified successfully with SM2")
return true, nil
default:
// 其他算法使用 crpt 通用接口
// 懒加载:解析公钥
if s.pubKey == nil {
keyType, err := s.config.SignatureAlgorithm.toKeyType()
if err != nil {
return false, err
}
pubKey, err := crpt.PublicKeyFromBytes(keyType, s.publicKey)
if err != nil {
log.Error("Failed to parse public key",
"algorithm", s.config.SignatureAlgorithm,
"error", err,
)
return false, fmt.Errorf("failed to parse public key: %w", err)
}
s.pubKey = pubKey
}
ok, err := crpt.VerifyMessage(s.pubKey, data, crpt.Signature(signature), nil)
if err != nil {
log.Error("Failed to verify with ConfigSigner",
"algorithm", s.config.SignatureAlgorithm,
"error", err,
)
return false, fmt.Errorf("failed to verify: %w", err)
}
if ok {
log.Debug("Verified successfully with ConfigSigner",
"algorithm", s.config.SignatureAlgorithm,
)
} else {
log.Warn("Verification failed with ConfigSigner",
"algorithm", s.config.SignatureAlgorithm,
)
}
return ok, nil
}
}
// GetAlgorithm 获取签名器使用的算法
func (s *ConfigSigner) GetAlgorithm() SignatureAlgorithm {
return s.config.SignatureAlgorithm
}