package crypto import ( "crypto/aes" "crypto/cipher" "crypto/rand" "encoding/base64" "errors" "io" ) // 加密密钥(生产环境应从配置文件读取) // 必须是 16、24 或 32 字节 const encryptionKey = "hfb-sys-2024-secret-key-32bytes!" // 正好32字节 // Encrypt 使用 AES-GCM 加密文本 func Encrypt(plainText string) (string, error) { block, err := aes.NewCipher([]byte(encryptionKey)) if err != nil { return "", err } aesGCM, err := cipher.NewGCM(block) if err != nil { return "", err } // 创建随机 nonce nonce := make([]byte, aesGCM.NonceSize()) if _, err := io.ReadFull(rand.Reader, nonce); err != nil { return "", err } // 加密并附加 nonce cipherBytes := aesGCM.Seal(nonce, nonce, []byte(plainText), nil) return base64.StdEncoding.EncodeToString(cipherBytes), nil } // Decrypt 使用 AES-GCM 解密文本 func Decrypt(cipherText string) (string, error) { block, err := aes.NewCipher([]byte(encryptionKey)) if err != nil { return "", err } aesGCM, err := cipher.NewGCM(block) if err != nil { return "", err } cipherBytes, err := base64.StdEncoding.DecodeString(cipherText) if err != nil { return "", err } nonceSize := aesGCM.NonceSize() if len(cipherBytes) < nonceSize { return "", errors.New("ciphertext too short") } // 提取 nonce 和实际密文 nonce, cipherBytes := cipherBytes[:nonceSize], cipherBytes[nonceSize:] plainBytes, err := aesGCM.Open(nil, nonce, cipherBytes, nil) if err != nil { return "", err } return string(plainBytes), nil }