Files
2026-06-06 17:49:22 +08:00

103 lines
2.2 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package paymentconfig
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"errors"
"io"
)
// Encryptor 密钥加密器接口
type Encryptor interface {
Encrypt(plaintext string) (string, error)
Decrypt(ciphertext string) (string, error)
}
// AESEncryptor AES 加密器
type AESEncryptor struct {
key []byte
}
// NewAESEncryptor 创建 AES 加密器
// key 必须是 16、24 或 32 字节(对应 AES-128、AES-192、AES-256
func NewAESEncryptor(key string) (*AESEncryptor, error) {
keyBytes := []byte(key)
if len(keyBytes) != 16 && len(keyBytes) != 24 && len(keyBytes) != 32 {
return nil, errors.New("invalid key length: must be 16, 24, or 32 bytes")
}
return &AESEncryptor{key: keyBytes}, nil
}
// Encrypt 加密明文(使用 AES-GCM
func (e *AESEncryptor) Encrypt(plaintext string) (string, error) {
if plaintext == "" {
return "", nil
}
block, err := aes.NewCipher(e.key)
if err != nil {
return "", err
}
gcm, err := cipher.NewGCM(block)
if err != nil {
return "", err
}
nonce := make([]byte, gcm.NonceSize())
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
return "", err
}
ciphertext := gcm.Seal(nonce, nonce, []byte(plaintext), nil)
return base64.StdEncoding.EncodeToString(ciphertext), nil
}
// Decrypt 解密密文(使用 AES-GCM
func (e *AESEncryptor) Decrypt(ciphertext string) (string, error) {
if ciphertext == "" {
return "", nil
}
ciphertextBytes, err := base64.StdEncoding.DecodeString(ciphertext)
if err != nil {
return "", err
}
block, err := aes.NewCipher(e.key)
if err != nil {
return "", err
}
gcm, err := cipher.NewGCM(block)
if err != nil {
return "", err
}
nonceSize := gcm.NonceSize()
if len(ciphertextBytes) < nonceSize {
return "", errors.New("ciphertext too short")
}
nonce, ciphertextBytes := ciphertextBytes[:nonceSize], ciphertextBytes[nonceSize:]
plaintext, err := gcm.Open(nil, nonce, ciphertextBytes, nil)
if err != nil {
return "", err
}
return string(plaintext), nil
}
// MockEncryptor 模拟加密器(用于测试)
type MockEncryptor struct{}
func (e *MockEncryptor) Encrypt(plaintext string) (string, error) {
return plaintext, nil
}
func (e *MockEncryptor) Decrypt(ciphertext string) (string, error) {
return ciphertext, nil
}