package utils import ( "crypto/aes" "crypto/cipher" "crypto/rand" "crypto/sha256" "encoding/base64" "io" "log" "os" ) var encryptKey []byte func init() { key := os.Getenv("ENCRYPT_KEY") if key == "" { key = "lan-manager-default-key-change-in-production" log.Println("[WARN] ENCRYPT_KEY not set, using default key. Please set ENCRYPT_KEY in production.") } h := sha256.Sum256([]byte(key)) encryptKey = h[:] } // Encrypt 使用 AES-GCM 加密明文,返回 base64 编码的密文 func Encrypt(plaintext string) (string, error) { if plaintext == "" { return "", nil } block, err := aes.NewCipher(encryptKey) 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 解密密文,输入为 base64 编码。 // 为了兼容升级前的明文密码,如果 base64 解码失败或解密失败,则直接返回原始字符串。 func Decrypt(ciphertext string) (string, error) { if ciphertext == "" { return "", nil } data, err := base64.StdEncoding.DecodeString(ciphertext) if err != nil { // 兼容旧明文密码 return ciphertext, nil } block, err := aes.NewCipher(encryptKey) if err != nil { return "", err } gcm, err := cipher.NewGCM(block) if err != nil { return "", err } nonceSize := gcm.NonceSize() if len(data) < nonceSize { // 兼容旧明文密码 return ciphertext, nil } nonce, cipherData := data[:nonceSize], data[nonceSize:] plain, err := gcm.Open(nil, nonce, cipherData, nil) if err != nil { // 兼容旧明文密码 return ciphertext, nil } return string(plain), nil }