2025-12-22 13:37:57 +08:00
|
|
|
|
package model
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
|
|
|
|
"github.com/crpt/go-crpt"
|
|
|
|
|
|
_ "github.com/crpt/go-crpt/ed25519" // 注册 Ed25519
|
|
|
|
|
|
_ "github.com/crpt/go-crpt/sm2" // 注册 SM2
|
|
|
|
|
|
|
2025-12-24 15:31:11 +08:00
|
|
|
|
"go.yandata.net/iod/iod/go-trustlog/api/logger"
|
2025-12-22 13:37:57 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
|
}
|