From 078967c6014491470a4135cc67e99afd2b742e49 Mon Sep 17 00:00:00 2001 From: bvbej Date: Wed, 21 Jan 2026 16:40:26 +0800 Subject: [PATCH] =?UTF-8?q?[=F0=9F=9A=80]=20add=20crypto=20pkg?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/crypto/aes.go | 71 +++++++++++++++++++++++++++++++++++ pkg/crypto/compress.go | 71 +++++++++++++++++++++++++++++++++++ pkg/crypto/hmac.go | 36 ++++++++++++++++++ pkg/crypto/interface.go | 22 +++++++++++ pkg/crypto/rsa.go | 83 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 283 insertions(+) create mode 100644 pkg/crypto/aes.go create mode 100644 pkg/crypto/compress.go create mode 100644 pkg/crypto/hmac.go create mode 100644 pkg/crypto/interface.go create mode 100644 pkg/crypto/rsa.go diff --git a/pkg/crypto/aes.go b/pkg/crypto/aes.go new file mode 100644 index 0000000..e9080a0 --- /dev/null +++ b/pkg/crypto/aes.go @@ -0,0 +1,71 @@ +package crypto + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "crypto/sha256" + "fmt" + "io" +) + +// AESEncryptor AES-GCM加密器 +type AESEncryptor struct { + key []byte +} + +// NewAESEncryptor 创建AES加密器 +func NewAESEncryptor(key string) (*AESEncryptor, error) { + // 使用SHA256生成32字节密钥 + hash := sha256.Sum256([]byte(key)) + return &AESEncryptor{key: hash[:]}, nil +} + +func (e *AESEncryptor) Encrypt(plaintext []byte) ([]byte, error) { + block, err := aes.NewCipher(e.key) + if err != nil { + return nil, fmt.Errorf("创建cipher失败: %w", err) + } + + gcm, err := cipher.NewGCM(block) + if err != nil { + return nil, fmt.Errorf("创建GCM失败: %w", err) + } + + nonce := make([]byte, gcm.NonceSize()) + if _, err := io.ReadFull(rand.Reader, nonce); err != nil { + return nil, fmt.Errorf("生成nonce失败: %w", err) + } + + ciphertext := gcm.Seal(nonce, nonce, plaintext, nil) + return ciphertext, nil +} + +func (e *AESEncryptor) Decrypt(ciphertext []byte) ([]byte, error) { + block, err := aes.NewCipher(e.key) + if err != nil { + return nil, fmt.Errorf("创建cipher失败: %w", err) + } + + gcm, err := cipher.NewGCM(block) + if err != nil { + return nil, fmt.Errorf("创建GCM失败: %w", err) + } + + nonceSize := gcm.NonceSize() + if len(ciphertext) < nonceSize { + return nil, fmt.Errorf("密文长度不足") + } + + nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:] + plaintext, err := gcm.Open(nil, nonce, ciphertext, nil) + if err != nil { + return nil, fmt.Errorf("解密失败: %w", err) + } + + return plaintext, nil +} + +func (e *AESEncryptor) Name() string { + return "AES-GCM-256" +} diff --git a/pkg/crypto/compress.go b/pkg/crypto/compress.go new file mode 100644 index 0000000..c838cca --- /dev/null +++ b/pkg/crypto/compress.go @@ -0,0 +1,71 @@ +package crypto + +import ( + "bytes" + "compress/gzip" + "io" +) + +// CompressEncryptor 压缩加密器 +type CompressEncryptor struct { + baseEncryptor Encryptor +} + +func NewCompressEncryptor(encryptor Encryptor) *CompressEncryptor { + return &CompressEncryptor{baseEncryptor: encryptor} +} + +// Encrypt 先压缩后加密 +func (c *CompressEncryptor) Encrypt(plaintext []byte) ([]byte, error) { + // 1. 压缩 + compressed, err := c.compress(plaintext) + if err != nil { + return nil, err + } + + // 2. 加密 + return c.baseEncryptor.Encrypt(compressed) +} + +// Decrypt 先解密后解压 +func (c *CompressEncryptor) Decrypt(ciphertext []byte) ([]byte, error) { + // 1. 解密 + compressed, err := c.baseEncryptor.Decrypt(ciphertext) + if err != nil { + return nil, err + } + + // 2. 解压 + return c.decompress(compressed) +} + +func (c *CompressEncryptor) Name() string { + return "GZIP-" + c.baseEncryptor.Name() +} + +// compress 使用gzip压缩 +func (c *CompressEncryptor) compress(data []byte) ([]byte, error) { + var buf bytes.Buffer + writer := gzip.NewWriter(&buf) + + if _, err := writer.Write(data); err != nil { + return nil, err + } + + if err := writer.Close(); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +// decompress 使用gzip解压 +func (c *CompressEncryptor) decompress(data []byte) ([]byte, error) { + reader, err := gzip.NewReader(bytes.NewReader(data)) + if err != nil { + return nil, err + } + defer func() { _ = reader.Close() }() + + return io.ReadAll(reader) +} diff --git a/pkg/crypto/hmac.go b/pkg/crypto/hmac.go new file mode 100644 index 0000000..1529b9d --- /dev/null +++ b/pkg/crypto/hmac.go @@ -0,0 +1,36 @@ +package crypto + +import ( + "crypto/hmac" + "crypto/sha256" + "fmt" +) + +// HMACSigner HMAC签名器 +type HMACSigner struct { + key []byte +} + +// NewHMACSigner 创建HMAC签名器 +func NewHMACSigner(key string) *HMACSigner { + return &HMACSigner{key: []byte(key)} +} + +func (s *HMACSigner) Sign(data []byte) ([]byte, error) { + h := hmac.New(sha256.New, s.key) + h.Write(data) + return h.Sum(nil), nil +} + +func (s *HMACSigner) Verify(data, signature []byte) error { + expected, err := s.Sign(data) + if err != nil { + return err + } + + if !hmac.Equal(expected, signature) { + return fmt.Errorf("签名验证失败") + } + + return nil +} diff --git a/pkg/crypto/interface.go b/pkg/crypto/interface.go new file mode 100644 index 0000000..17a3b37 --- /dev/null +++ b/pkg/crypto/interface.go @@ -0,0 +1,22 @@ +package crypto + +// Encryptor 加密器接口 +type Encryptor interface { + // Encrypt 加密数据 + Encrypt(plaintext []byte) ([]byte, error) + + // Decrypt 解密数据 + Decrypt(ciphertext []byte) ([]byte, error) + + // Name 返回加密算法名称 + Name() string +} + +// Signer 签名器接口 +type Signer interface { + // Sign 生成签名 + Sign(data []byte) ([]byte, error) + + // Verify 验证签名 + Verify(data, signature []byte) error +} diff --git a/pkg/crypto/rsa.go b/pkg/crypto/rsa.go new file mode 100644 index 0000000..fb86453 --- /dev/null +++ b/pkg/crypto/rsa.go @@ -0,0 +1,83 @@ +package crypto + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/sha256" + "crypto/x509" + "encoding/pem" + "fmt" +) + +// RSAEncryptor RSA加密器 +type RSAEncryptor struct { + publicKey *rsa.PublicKey + privateKey *rsa.PrivateKey +} + +// NewRSAEncryptor 创建RSA加密器 +func NewRSAEncryptor(publicKeyPEM, privateKeyPEM []byte) (*RSAEncryptor, error) { + encryptor := &RSAEncryptor{} + + if len(publicKeyPEM) > 0 { + block, _ := pem.Decode(publicKeyPEM) + if block == nil { + return nil, fmt.Errorf("解析公钥失败") + } + + pub, err := x509.ParsePKIXPublicKey(block.Bytes) + if err != nil { + return nil, fmt.Errorf("解析公钥失败: %w", err) + } + + var ok bool + encryptor.publicKey, ok = pub.(*rsa.PublicKey) + if !ok { + return nil, fmt.Errorf("不是RSA公钥") + } + } else { + return nil, fmt.Errorf("公钥未设置") + } + + if len(privateKeyPEM) > 0 { + block, _ := pem.Decode(privateKeyPEM) + if block == nil { + return nil, fmt.Errorf("解析私钥失败") + } + + priv, err := x509.ParsePKCS8PrivateKey(block.Bytes) + if err != nil { + return nil, fmt.Errorf("解析私钥失败: %w", err) + } + + var ok bool + encryptor.privateKey, ok = priv.(*rsa.PrivateKey) + if !ok { + return nil, fmt.Errorf("不是RSA私钥") + } + } else { + return nil, fmt.Errorf("私钥未设置") + } + + return encryptor, nil +} + +func (e *RSAEncryptor) Encrypt(plaintext []byte) ([]byte, error) { + if e.publicKey == nil { + return nil, fmt.Errorf("公钥未设置") + } + + return rsa.EncryptOAEP(sha256.New(), rand.Reader, e.publicKey, plaintext, nil) +} + +func (e *RSAEncryptor) Decrypt(ciphertext []byte) ([]byte, error) { + if e.privateKey == nil { + return nil, fmt.Errorf("私钥未设置") + } + + return rsa.DecryptOAEP(sha256.New(), rand.Reader, e.privateKey, ciphertext, nil) +} + +func (e *RSAEncryptor) Name() string { + return "RSA-OAEP-SHA256" +}