修复启动卡住:加密迁移解密失败时跳过而非崩溃

未设置 APP_ENCRYPTION_KEY 时使用临时密钥,重启后密钥变更导致旧密文解密失败。
改为跳过无法解密的值并记录警告,不再阻塞启动。
This commit is contained in:
yml2213
2026-06-24 16:00:07 +08:00
parent e478ac4d09
commit a697e8735a
+14 -2
View File
@@ -13,6 +13,7 @@ from Crypto.Cipher import AES
from sqlalchemy import text from sqlalchemy import text
from sqlalchemy.engine import Engine from sqlalchemy.engine import Engine
from sqlalchemy.types import Text, TypeDecorator from sqlalchemy.types import Text, TypeDecorator
from loguru import logger
_PREFIX = "enc:v1:" _PREFIX = "enc:v1:"
@@ -164,7 +165,10 @@ def _table_exists(engine: Engine, table_name: str) -> bool:
def encrypt_existing_sensitive_data(engine: Engine) -> int: def encrypt_existing_sensitive_data(engine: Engine) -> int:
"""把历史明文敏感字段迁移成密文;已加密但非主密钥的值会重加密。""" """把历史明文敏感字段迁移成密文;已加密但非主密钥的值会重加密。
解密失败的值(密钥丢失/变更)会被跳过并记录警告。
"""
primary_name = _key_candidates()[0].name primary_name = _key_candidates()[0].name
changed = 0 changed = 0
@@ -179,7 +183,15 @@ def encrypt_existing_sensitive_data(engine: Engine) -> int:
raw_value = row[column_name] raw_value = row[column_name]
if raw_value is None or raw_value == "": if raw_value is None or raw_value == "":
continue continue
plain_value, key_name = decrypt_value_with_key_name(str(raw_value)) try:
plain_value, key_name = decrypt_value_with_key_name(str(raw_value))
except ValueError:
# 解密失败(密钥变更/丢失),跳过该值,避免启动阻塞
logger.warning(
f"跳过无法解密的字段 {table_name}.{column_name}[id={row['id']}]"
f"可能是加密密钥已变更"
)
continue
if is_encrypted(str(raw_value)) and key_name == primary_name: if is_encrypted(str(raw_value)) and key_name == primary_name:
continue continue
encrypted = encrypt_value(plain_value) encrypted = encrypt_value(plain_value)