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:
310
api/model/crypto_config.go
Normal file
310
api/model/crypto_config.go
Normal file
@@ -0,0 +1,310 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
"github.com/crpt/go-crpt"
|
||||
_ "github.com/crpt/go-crpt/ed25519" // Import Ed25519
|
||||
_ "github.com/crpt/go-crpt/sm2" // Import SM2
|
||||
|
||||
"go.yandata.net/iod/iod/trustlog-sdk/api/logger"
|
||||
)
|
||||
|
||||
// SignatureAlgorithm 定义支持的签名算法类型.
|
||||
type SignatureAlgorithm string
|
||||
|
||||
const (
|
||||
// SM2 国密SM2算法
|
||||
SM2Algorithm SignatureAlgorithm = "sm2"
|
||||
// Ed25519 Ed25519算法
|
||||
Ed25519Algorithm SignatureAlgorithm = "ed25519"
|
||||
)
|
||||
|
||||
// CryptoConfig 密码学配置
|
||||
type CryptoConfig struct {
|
||||
// SignatureAlgorithm 签名算法类型
|
||||
// SM2 会自动使用 SM3 哈希,Ed25519 会使用 SHA512 哈希
|
||||
SignatureAlgorithm SignatureAlgorithm
|
||||
}
|
||||
|
||||
var (
|
||||
// 默认配置:使用 SM2(内部自动使用 SM3)
|
||||
defaultConfig = &CryptoConfig{
|
||||
SignatureAlgorithm: SM2Algorithm,
|
||||
}
|
||||
|
||||
// 全局配置
|
||||
globalConfig *CryptoConfig
|
||||
globalConfigMutex sync.RWMutex
|
||||
|
||||
// ErrUnsupportedAlgorithm 不支持的算法错误
|
||||
ErrUnsupportedAlgorithm = errors.New("unsupported signature algorithm")
|
||||
)
|
||||
|
||||
func init() {
|
||||
// 自动初始化全局配置为 SM2
|
||||
globalConfig = defaultConfig
|
||||
logger.GetGlobalLogger().Debug("Crypto config initialized with default SM2")
|
||||
}
|
||||
|
||||
// SetGlobalCryptoConfig 设置全局密码学配置
|
||||
func SetGlobalCryptoConfig(config *CryptoConfig) error {
|
||||
if config == nil {
|
||||
return errors.New("config cannot be nil")
|
||||
}
|
||||
|
||||
// 验证配置
|
||||
if err := config.Validate(); err != nil {
|
||||
return fmt.Errorf("invalid config: %w", err)
|
||||
}
|
||||
|
||||
globalConfigMutex.Lock()
|
||||
defer globalConfigMutex.Unlock()
|
||||
|
||||
globalConfig = config
|
||||
logger.GetGlobalLogger().Info("Global crypto config updated",
|
||||
"signatureAlgorithm", config.SignatureAlgorithm,
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetGlobalCryptoConfig 获取全局密码学配置
|
||||
func GetGlobalCryptoConfig() *CryptoConfig {
|
||||
globalConfigMutex.RLock()
|
||||
defer globalConfigMutex.RUnlock()
|
||||
|
||||
if globalConfig == nil {
|
||||
return defaultConfig
|
||||
}
|
||||
return globalConfig
|
||||
}
|
||||
|
||||
// Validate 验证配置是否有效
|
||||
func (c *CryptoConfig) Validate() error {
|
||||
// 验证签名算法
|
||||
switch c.SignatureAlgorithm {
|
||||
case SM2Algorithm, Ed25519Algorithm:
|
||||
// 支持的算法
|
||||
default:
|
||||
return fmt.Errorf("%w: %s", ErrUnsupportedAlgorithm, c.SignatureAlgorithm)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// toKeyType 将 SignatureAlgorithm 转换为 crpt.KeyType
|
||||
func (a SignatureAlgorithm) toKeyType() (crpt.KeyType, error) {
|
||||
switch a {
|
||||
case SM2Algorithm:
|
||||
return crpt.SM2, nil
|
||||
case Ed25519Algorithm:
|
||||
return crpt.Ed25519, nil
|
||||
default:
|
||||
return 0, fmt.Errorf("%w: %s", ErrUnsupportedAlgorithm, a)
|
||||
}
|
||||
}
|
||||
|
||||
// KeyPair 通用密钥对,支持多种算法
|
||||
type KeyPair struct {
|
||||
Public crpt.PublicKey `json:"publicKey"`
|
||||
Private crpt.PrivateKey `json:"privateKey"`
|
||||
Algorithm SignatureAlgorithm
|
||||
}
|
||||
|
||||
// GenerateKeyPair 根据配置生成密钥对
|
||||
func GenerateKeyPair(config *CryptoConfig) (*KeyPair, error) {
|
||||
if config == nil {
|
||||
config = GetGlobalCryptoConfig()
|
||||
}
|
||||
|
||||
log := logger.GetGlobalLogger()
|
||||
log.Debug("Generating key pair",
|
||||
"algorithm", config.SignatureAlgorithm,
|
||||
)
|
||||
|
||||
keyType, err := config.SignatureAlgorithm.toKeyType()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pub, priv, err := crpt.GenerateKey(keyType, rand.Reader)
|
||||
if err != nil {
|
||||
log.Error("Failed to generate key pair",
|
||||
"algorithm", config.SignatureAlgorithm,
|
||||
"error", err,
|
||||
)
|
||||
return nil, fmt.Errorf("failed to generate %s key pair: %w", config.SignatureAlgorithm, err)
|
||||
}
|
||||
|
||||
log.Debug("Key pair generated successfully",
|
||||
"algorithm", config.SignatureAlgorithm,
|
||||
)
|
||||
|
||||
return &KeyPair{
|
||||
Public: pub,
|
||||
Private: priv,
|
||||
Algorithm: config.SignatureAlgorithm,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Sign 使用密钥对签名数据
|
||||
func (kp *KeyPair) Sign(data []byte, rand io.Reader) ([]byte, error) {
|
||||
if rand == nil {
|
||||
rand = defaultRand()
|
||||
}
|
||||
|
||||
log := logger.GetGlobalLogger()
|
||||
log.Debug("Signing data",
|
||||
"algorithm", kp.Algorithm,
|
||||
"dataLength", len(data),
|
||||
)
|
||||
|
||||
signature, err := crpt.SignMessage(kp.Private, data, rand, nil)
|
||||
if err != nil {
|
||||
log.Error("Failed to sign data",
|
||||
"algorithm", kp.Algorithm,
|
||||
"error", err,
|
||||
)
|
||||
return nil, fmt.Errorf("failed to sign with %s: %w", kp.Algorithm, err)
|
||||
}
|
||||
|
||||
log.Debug("Data signed successfully",
|
||||
"algorithm", kp.Algorithm,
|
||||
"signatureLength", len(signature),
|
||||
)
|
||||
return signature, nil
|
||||
}
|
||||
|
||||
// Verify 使用公钥验证签名
|
||||
func (kp *KeyPair) Verify(data, signature []byte) (bool, error) {
|
||||
log := logger.GetGlobalLogger()
|
||||
log.Debug("Verifying signature",
|
||||
"algorithm", kp.Algorithm,
|
||||
"dataLength", len(data),
|
||||
"signatureLength", len(signature),
|
||||
)
|
||||
|
||||
ok, err := crpt.VerifyMessage(kp.Public, data, crpt.Signature(signature), nil)
|
||||
if err != nil {
|
||||
log.Error("Failed to verify signature",
|
||||
"algorithm", kp.Algorithm,
|
||||
"error", err,
|
||||
)
|
||||
return false, fmt.Errorf("failed to verify with %s: %w", kp.Algorithm, err)
|
||||
}
|
||||
|
||||
if ok {
|
||||
log.Debug("Signature verified successfully",
|
||||
"algorithm", kp.Algorithm,
|
||||
)
|
||||
} else {
|
||||
log.Warn("Signature verification failed",
|
||||
"algorithm", kp.Algorithm,
|
||||
)
|
||||
}
|
||||
|
||||
return ok, nil
|
||||
}
|
||||
|
||||
// MarshalPrivateKey 序列化私钥
|
||||
func (kp *KeyPair) MarshalPrivateKey() ([]byte, error) {
|
||||
if kp.Private == nil {
|
||||
return nil, errors.New("private key is nil")
|
||||
}
|
||||
return kp.Private.Bytes(), nil
|
||||
}
|
||||
|
||||
// MarshalPublicKey 序列化公钥
|
||||
func (kp *KeyPair) MarshalPublicKey() ([]byte, error) {
|
||||
if kp.Public == nil {
|
||||
return nil, errors.New("public key is nil")
|
||||
}
|
||||
return kp.Public.Bytes(), nil
|
||||
}
|
||||
|
||||
// ParsePrivateKey 解析私钥
|
||||
func ParsePrivateKey(data []byte, algorithm SignatureAlgorithm) (crpt.PrivateKey, error) {
|
||||
keyType, err := algorithm.toKeyType()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return crpt.PrivateKeyFromBytes(keyType, data)
|
||||
}
|
||||
|
||||
// ParsePublicKey 解析公钥
|
||||
func ParsePublicKey(data []byte, algorithm SignatureAlgorithm) (crpt.PublicKey, error) {
|
||||
keyType, err := algorithm.toKeyType()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return crpt.PublicKeyFromBytes(keyType, data)
|
||||
}
|
||||
|
||||
// defaultRand 返回默认的随机数生成器
|
||||
func defaultRand() io.Reader {
|
||||
return rand.Reader
|
||||
}
|
||||
|
||||
// SignWithConfig 使用指定配置签名数据
|
||||
func SignWithConfig(data, privateKeyDER []byte, config *CryptoConfig) ([]byte, error) {
|
||||
if config == nil {
|
||||
config = GetGlobalCryptoConfig()
|
||||
}
|
||||
|
||||
log := logger.GetGlobalLogger()
|
||||
log.Debug("Signing with config",
|
||||
"algorithm", config.SignatureAlgorithm,
|
||||
"dataLength", len(data),
|
||||
)
|
||||
|
||||
privateKey, err := ParsePrivateKey(privateKeyDER, config.SignatureAlgorithm)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse private key: %w", err)
|
||||
}
|
||||
|
||||
signature, err := crpt.SignMessage(privateKey, data, rand.Reader, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to sign: %w", err)
|
||||
}
|
||||
|
||||
log.Debug("Signed with config successfully",
|
||||
"algorithm", config.SignatureAlgorithm,
|
||||
"signatureLength", len(signature),
|
||||
)
|
||||
return signature, nil
|
||||
}
|
||||
|
||||
// VerifyWithConfig 使用指定配置验证签名
|
||||
func VerifyWithConfig(data, publicKeyDER, signature []byte, config *CryptoConfig) (bool, error) {
|
||||
if config == nil {
|
||||
config = GetGlobalCryptoConfig()
|
||||
}
|
||||
|
||||
log := logger.GetGlobalLogger()
|
||||
log.Debug("Verifying with config",
|
||||
"algorithm", config.SignatureAlgorithm,
|
||||
"dataLength", len(data),
|
||||
)
|
||||
|
||||
publicKey, err := ParsePublicKey(publicKeyDER, config.SignatureAlgorithm)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to parse public key: %w", err)
|
||||
}
|
||||
|
||||
ok, err := crpt.VerifyMessage(publicKey, data, crpt.Signature(signature), nil)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to verify: %w", err)
|
||||
}
|
||||
|
||||
log.Debug("Verified with config",
|
||||
"algorithm", config.SignatureAlgorithm,
|
||||
"result", ok,
|
||||
)
|
||||
return ok, nil
|
||||
}
|
||||
Reference in New Issue
Block a user