Files
nl-blogs/server/utils/encrypt.go
2026-07-14 10:05:33 +08:00

96 lines
2.0 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 utils
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"errors"
"io"
"os"
"strings"
)
// defaultAESKey 必须精确为 16/24/32 字节;此处为 AES-25632 字节)
var defaultAESKey = []byte("art-code-blog-aes256-key-32b!!!!") // len == 32
// GetAESKey 获取 AES 密钥:优先 AES_ENCRYPTION_KEY否则使用默认密钥长度非法时用 SHA-256 规范化为 32 字节
func GetAESKey() []byte {
key := strings.TrimSpace(os.Getenv("AES_ENCRYPTION_KEY"))
if key == "" {
return normalizeAESKey(defaultAESKey)
}
return normalizeAESKey([]byte(key))
}
func normalizeAESKey(key []byte) []byte {
switch len(key) {
case 16, 24, 32:
return key
default:
sum := sha256.Sum256(key)
out := make([]byte, 32)
copy(out, sum[:])
return out
}
}
// EncryptAES 使用AES-256-GCM加密数据
func EncryptAES(plaintext string) (string, error) {
key := GetAESKey()
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
aesGCM, err := cipher.NewGCM(block)
if err != nil {
return "", err
}
nonce := make([]byte, aesGCM.NonceSize())
if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
return "", err
}
ciphertext := aesGCM.Seal(nonce, nonce, []byte(plaintext), nil)
return base64.StdEncoding.EncodeToString(ciphertext), nil
}
// DecryptAES 使用AES-256-GCM解密数据
func DecryptAES(encrypted string) (string, error) {
key := GetAESKey()
ciphertext, err := base64.StdEncoding.DecodeString(encrypted)
if err != nil {
return "", err
}
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
aesGCM, err := cipher.NewGCM(block)
if err != nil {
return "", err
}
nonceSize := aesGCM.NonceSize()
if len(ciphertext) < nonceSize {
return "", errors.New("ciphertext too short")
}
nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]
plaintext, err := aesGCM.Open(nil, nonce, ciphertext, nil)
if err != nil {
return "", err
}
return string(plaintext), nil
}