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

未设置 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.engine import Engine
from sqlalchemy.types import Text, TypeDecorator
from loguru import logger
_PREFIX = "enc:v1:"
@@ -164,7 +165,10 @@ def _table_exists(engine: Engine, table_name: str) -> bool:
def encrypt_existing_sensitive_data(engine: Engine) -> int:
"""把历史明文敏感字段迁移成密文;已加密但非主密钥的值会重加密。"""
"""把历史明文敏感字段迁移成密文;已加密但非主密钥的值会重加密。
解密失败的值(密钥丢失/变更)会被跳过并记录警告。
"""
primary_name = _key_candidates()[0].name
changed = 0
@@ -179,7 +183,15 @@ def encrypt_existing_sensitive_data(engine: Engine) -> int:
raw_value = row[column_name]
if raw_value is None or raw_value == "":
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:
continue
encrypted = encrypt_value(plain_value)