package crypto import ( "crypto/aes" "crypto/cipher" "crypto/rand" "crypto/sha256" "encoding/base64" "fmt" "io" "lain/config" ) func getKey() []byte { hash := sha256.Sum256([]byte(config.Server.AppSecret)) return hash[:] } func Encrypt(plaintext string) (string, error) { key := getKey() block, err := aes.NewCipher(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.URLEncoding.EncodeToString(ciphertext), nil } func Decrypt(ciphertext string) (string, error) { key := getKey() ciphertextBytes, err := base64.URLEncoding.DecodeString(ciphertext) if err != nil { return "", err } block, err := aes.NewCipher(key) if err != nil { return "", err } gcm, err := cipher.NewGCM(block) if err != nil { return "", err } nonceSize := gcm.NonceSize() if len(ciphertextBytes) < nonceSize { return "", fmt.Errorf("ciphertext too short") } nonce, ciphertextBytes := ciphertextBytes[:nonceSize], ciphertextBytes[nonceSize:] plaintextBytes, err := gcm.Open(nil, nonce, ciphertextBytes, nil) if err != nil { return "", err } return string(plaintextBytes), nil }