[🚀] add crypto pkg

This commit is contained in:
2026-01-21 16:40:26 +08:00
parent 424ad78a7e
commit 078967c601
5 changed files with 283 additions and 0 deletions

71
pkg/crypto/aes.go Normal file
View File

@@ -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"
}

71
pkg/crypto/compress.go Normal file
View File

@@ -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)
}

36
pkg/crypto/hmac.go Normal file
View File

@@ -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
}

22
pkg/crypto/interface.go Normal file
View File

@@ -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
}

83
pkg/crypto/rsa.go Normal file
View File

@@ -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"
}