Files
user-system/internal/security/encryption.go
long-agent 582ad7a069 test: add comprehensive test coverage and improve code quality
- Add new test files for auth, service, and handler modules
- Improve test organization and coverage
- Refactor code for better maintainability
- Add captcha, settings, stats, and theme handler tests
- Add auth module tests (CAS, OAuth, password, SSO, state)
- Add service layer tests for auth, export, permissions, roles
- All Go tests pass (exit code 0)
- All frontend tests pass (325 tests in 59 files)
2026-04-17 20:43:50 +08:00

96 lines
1.9 KiB
Go
Raw 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 security
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"errors"
"io"
"strings"
)
// Encryption 加密工具
type Encryption struct {
key []byte
}
// NewEncryption 创建加密工具密钥长度必须是16, 24或32字节
func NewEncryption(key string) (*Encryption, error) {
if len(key) != 16 && len(key) != 24 && len(key) != 32 {
return nil, errors.New("key length must be 16, 24 or 32 bytes")
}
return &Encryption{key: []byte(key)}, nil
}
// Encrypt 使用AES-256-GCM加密
func (e *Encryption) Encrypt(plaintext string) (string, error) {
block, err := aes.NewCipher(e.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.StdEncoding.EncodeToString(ciphertext), nil
}
// Decrypt 使用AES-256-GCM解密
func (e *Encryption) Decrypt(ciphertext string) (string, error) {
data, err := base64.StdEncoding.DecodeString(ciphertext)
if err != nil {
return "", err
}
block, err := aes.NewCipher(e.key)
if err != nil {
return "", err
}
gcm, err := cipher.NewGCM(block)
if err != nil {
return "", err
}
nonceSize := gcm.NonceSize()
if len(data) < nonceSize {
return "", errors.New("ciphertext too short")
}
nonce, cipherData := data[:nonceSize], data[nonceSize:]
plaintext, err := gcm.Open(nil, nonce, cipherData, nil)
if err != nil {
return "", err
}
return string(plaintext), nil
}
// MaskEmail 邮箱脱敏
func MaskEmail(email string) string {
if email == "" {
return ""
}
prefix := email[:3]
suffix := email[strings.Index(email, "@"):]
return prefix + "***" + suffix
}
// MaskPhone 手机号脱敏
func MaskPhone(phone string) string {
if len(phone) != 11 {
return phone
}
return phone[:3] + "****" + phone[7:]
}