[🚀] add crypto pkg
This commit is contained in:
71
pkg/crypto/aes.go
Normal file
71
pkg/crypto/aes.go
Normal 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
71
pkg/crypto/compress.go
Normal 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
36
pkg/crypto/hmac.go
Normal 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
22
pkg/crypto/interface.go
Normal 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
83
pkg/crypto/rsa.go
Normal 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"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user