222 lines
5.9 KiB
Go
222 lines
5.9 KiB
Go
package utility
|
||
|
||
import (
|
||
"crypto/aes"
|
||
"crypto/cipher"
|
||
"crypto/rand"
|
||
"encoding/base64"
|
||
"errors"
|
||
"fmt"
|
||
"io"
|
||
)
|
||
|
||
// 加密key
|
||
var CryptoKey = "ProxyServer@#(123321)!Keycrypto"
|
||
|
||
// CryptoHelper 加密帮助类
|
||
type CryptoHelper struct {
|
||
key []byte
|
||
}
|
||
|
||
// NewCryptoHelper 创建新的加密帮助实例
|
||
// key: 32字节的加密密钥,如果长度不足会自动填充,超出会截断
|
||
func NewCryptoHelper(key string) *CryptoHelper {
|
||
// 确保密钥长度为32字节(AES-256)
|
||
keyBytes := make([]byte, 32)
|
||
copy(keyBytes, []byte(key))
|
||
return &CryptoHelper{
|
||
key: keyBytes,
|
||
}
|
||
}
|
||
|
||
// Encrypt 加密字符串
|
||
// plaintext: 要加密的明文
|
||
// 返回: base64编码的密文和错误信息
|
||
func (c *CryptoHelper) Encrypt(plaintext string) (string, error) {
|
||
if plaintext == "" {
|
||
return "", errors.New("plaintext cannot be empty")
|
||
}
|
||
|
||
// 创建AES cipher
|
||
block, err := aes.NewCipher(c.key)
|
||
if err != nil {
|
||
return "", fmt.Errorf("failed to create cipher: %w", err)
|
||
}
|
||
|
||
// 使用GCM模式
|
||
gcm, err := cipher.NewGCM(block)
|
||
if err != nil {
|
||
return "", fmt.Errorf("failed to create GCM: %w", err)
|
||
}
|
||
|
||
// 生成随机nonce
|
||
nonce := make([]byte, gcm.NonceSize())
|
||
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
|
||
return "", fmt.Errorf("failed to generate nonce: %w", err)
|
||
}
|
||
|
||
// 加密数据
|
||
ciphertext := gcm.Seal(nonce, nonce, []byte(plaintext), nil)
|
||
|
||
// 返回base64编码的结果
|
||
return base64.StdEncoding.EncodeToString(ciphertext), nil
|
||
}
|
||
|
||
// Decrypt 解密字符串
|
||
// ciphertext: base64编码的密文
|
||
// 返回: 解密后的明文和错误信息
|
||
func (c *CryptoHelper) Decrypt(ciphertext string) (string, error) {
|
||
if ciphertext == "" {
|
||
return "", errors.New("ciphertext cannot be empty")
|
||
}
|
||
|
||
// base64解码
|
||
data, err := base64.StdEncoding.DecodeString(ciphertext)
|
||
if err != nil {
|
||
return "", fmt.Errorf("failed to decode base64: %w", err)
|
||
}
|
||
|
||
// 创建AES cipher
|
||
block, err := aes.NewCipher(c.key)
|
||
if err != nil {
|
||
return "", fmt.Errorf("failed to create cipher: %w", err)
|
||
}
|
||
|
||
// 使用GCM模式
|
||
gcm, err := cipher.NewGCM(block)
|
||
if err != nil {
|
||
return "", fmt.Errorf("failed to create GCM: %w", err)
|
||
}
|
||
|
||
// 检查数据长度
|
||
nonceSize := gcm.NonceSize()
|
||
if len(data) < nonceSize {
|
||
return "", errors.New("ciphertext too short")
|
||
}
|
||
|
||
// 提取nonce和密文
|
||
nonce, cipherData := data[:nonceSize], data[nonceSize:]
|
||
|
||
// 解密数据
|
||
plaintext, err := gcm.Open(nil, nonce, cipherData, nil)
|
||
if err != nil {
|
||
return "", fmt.Errorf("failed to decrypt: %w", err)
|
||
}
|
||
|
||
return string(plaintext), nil
|
||
}
|
||
|
||
// EncryptBytes 加密字节数组
|
||
// data: 要加密的字节数组
|
||
// 返回: 加密后的字节数组和错误信息
|
||
func (c *CryptoHelper) EncryptBytes(data []byte) ([]byte, error) {
|
||
if len(data) == 0 {
|
||
return nil, errors.New("data cannot be empty")
|
||
}
|
||
|
||
// 创建AES cipher
|
||
block, err := aes.NewCipher(c.key)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("failed to create cipher: %w", err)
|
||
}
|
||
|
||
// 使用GCM模式
|
||
gcm, err := cipher.NewGCM(block)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("failed to create GCM: %w", err)
|
||
}
|
||
|
||
// 生成随机nonce
|
||
nonce := make([]byte, gcm.NonceSize())
|
||
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
|
||
return nil, fmt.Errorf("failed to generate nonce: %w", err)
|
||
}
|
||
|
||
// 加密数据
|
||
ciphertext := gcm.Seal(nonce, nonce, data, nil)
|
||
|
||
return ciphertext, nil
|
||
}
|
||
|
||
// DecryptBytes 解密字节数组
|
||
// ciphertext: 加密后的字节数组
|
||
// 返回: 解密后的字节数组和错误信息
|
||
func (c *CryptoHelper) DecryptBytes(ciphertext []byte) ([]byte, error) {
|
||
if len(ciphertext) == 0 {
|
||
return nil, errors.New("ciphertext cannot be empty")
|
||
}
|
||
|
||
// 创建AES cipher
|
||
block, err := aes.NewCipher(c.key)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("failed to create cipher: %w", err)
|
||
}
|
||
|
||
// 使用GCM模式
|
||
gcm, err := cipher.NewGCM(block)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("failed to create GCM: %w", err)
|
||
}
|
||
|
||
// 检查数据长度
|
||
nonceSize := gcm.NonceSize()
|
||
if len(ciphertext) < nonceSize {
|
||
return nil, errors.New("ciphertext too short")
|
||
}
|
||
|
||
// 提取nonce和密文
|
||
nonce, cipherData := ciphertext[:nonceSize], ciphertext[nonceSize:]
|
||
|
||
// 解密数据
|
||
plaintext, err := gcm.Open(nil, nonce, cipherData, nil)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("failed to decrypt: %w", err)
|
||
}
|
||
|
||
return plaintext, nil
|
||
}
|
||
|
||
// GenerateKey 生成随机密钥
|
||
// 返回: 32字节的随机密钥字符串
|
||
func GenerateKey() (string, error) {
|
||
key := make([]byte, 32)
|
||
if _, err := io.ReadFull(rand.Reader, key); err != nil {
|
||
return "", fmt.Errorf("failed to generate key: %w", err)
|
||
}
|
||
return base64.StdEncoding.EncodeToString(key), nil
|
||
}
|
||
|
||
// QuickEncrypt 快速加密函数(使用默认密钥)
|
||
// plaintext: 要加密的明文
|
||
// key: 加密密钥
|
||
// 返回: base64编码的密文和错误信息
|
||
func QuickEncrypt(plaintext, key string) (string, error) {
|
||
crypto := NewCryptoHelper(key)
|
||
return crypto.Encrypt(plaintext)
|
||
}
|
||
|
||
// QuickDecrypt2 快速解密函数(使用默认密钥)
|
||
// ciphertext: base64编码的密文
|
||
// 返回: 解密后的明文和错误信息
|
||
func QuickDecrypt2(ciphertext string) (string, error) {
|
||
crypto := NewCryptoHelper(CryptoKey)
|
||
return crypto.Decrypt(ciphertext)
|
||
}
|
||
|
||
// QuickEncrypt2 快速加密函数(使用默认密钥)
|
||
// plaintext: 要加密的明文
|
||
// 返回: base64编码的密文和错误信息
|
||
func QuickEncrypt2(plaintext string) (string, error) {
|
||
crypto := NewCryptoHelper(CryptoKey)
|
||
return crypto.Encrypt(plaintext)
|
||
}
|
||
|
||
// QuickDecrypt 快速解密函数(使用默认密钥)
|
||
// ciphertext: base64编码的密文
|
||
// key: 解密密钥
|
||
// 返回: 解密后的明文和错误信息
|
||
func QuickDecrypt(ciphertext, key string) (string, error) {
|
||
crypto := NewCryptoHelper(key)
|
||
return crypto.Decrypt(ciphertext)
|
||
}
|