AES 字段加密迁配置并兼容旧密文

移除字段加密硬编码主密钥,改为 FIELD_ENCRYPTION_KEY 注入。

保留 FIELD_ENCRYPTION_LEGACY_KEY 透明回退旧密文,新写入统一使用主密钥;生产环境校验主密钥和 legacy 密钥长度、占位符及相等关系,并统一生产环境判断口径。

补充配置与旧密文兼容回归测试。
This commit is contained in:
yml
2026-06-14 17:53:24 +08:00
parent 64f7ed3753
commit 8fef037be3
15 changed files with 519 additions and 82 deletions
@@ -13,14 +13,16 @@ import (
"gorm.io/gorm"
)
// 删除加密密钥常量
type Repository struct {
db *gorm.DB
db *gorm.DB
encryptor crypto.Encryptor
}
func NewRepository(db *gorm.DB) *Repository {
return &Repository{db: db}
func NewRepository(db *gorm.DB, encryptor crypto.Encryptor) *Repository {
if encryptor == nil {
encryptor = &crypto.MockEncryptor{}
}
return &Repository{db: db, encryptor: encryptor}
}
func (r *Repository) List(ctx context.Context, userID uint64, page, pageSize int) (*PaginatedResult, error) {
@@ -73,7 +75,7 @@ func (r *Repository) FindByID(ctx context.Context, userID, id uint64) (*PaymentA
func (r *Repository) Create(ctx context.Context, userID uint64, req CreatePaymentAccountRequest) (*PaymentAccountDTO, error) {
db := r.db.WithContext(ctx)
// 加密账号
encryptedNo, err := crypto.Encrypt(req.AccountNo)
encryptedNo, err := r.encryptor.Encrypt(req.AccountNo)
if err != nil {
return nil, err
}
@@ -217,7 +219,7 @@ func (r *Repository) ValidateRealname(ctx context.Context, userID uint64, accoun
// 验证姓名匹配 - 使用加密字段进行精确匹配
if realname.EncryptedName != "" {
// 有加密字段,解密后精确匹配
decryptedName, err := crypto.Decrypt(realname.EncryptedName)
decryptedName, err := r.encryptor.Decrypt(realname.EncryptedName)
if err != nil {
// 解密失败,降级到前缀匹配
return r.validateByMaskedName(realname.MaskedName, accountName)
@@ -256,7 +258,7 @@ func (r *Repository) validateByMaskedName(maskedName, accountName string) error
func (r *Repository) toDTO(account model.UserPaymentAccount) (*PaymentAccountDTO, error) {
// 解密账号并脱敏
decrypted, err := crypto.Decrypt(account.AccountNo)
decrypted, err := r.encryptor.Decrypt(account.AccountNo)
if err != nil {
decrypted = account.AccountNo // 降级处理
}
@@ -314,5 +316,5 @@ func (r *Repository) GetDecryptedAccountNo(ctx context.Context, userID, id uint6
if err := r.db.WithContext(ctx).Where("id = ? AND user_id = ?", id, userID).First(&account).Error; err != nil {
return "", err
}
return crypto.Decrypt(account.AccountNo)
return r.encryptor.Decrypt(account.AccountNo)
}