You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI与SQLAlchemy:加密表列查询解密遇填充错误

解决StringEncryptedType解密时的binascii.Error: Incorrect padding问题

你遇到的Incorrect padding错误是Base64解密阶段的异常,通常和加密密钥不匹配、数据库存在未加密旧数据或加密配置不一致有关,以下是具体排查和修复方案:

1. 验证加密密钥的正确性

  • 确保settings.ENCRYPT_KEY的长度符合AES加密要求:AES-128需要16位、AES-192需要24位、AES-256需要32位,密钥长度不符会直接导致加密/解密数据格式异常。
  • 确认当前使用的密钥和最初加密数据时的密钥完全一致,包括大小写、特殊字符,任何细微差异都会引发解密失败。

2. 处理数据库中的未加密旧数据

如果你的users表之前phone_number列是普通字符串类型,后来才改为StringEncryptedType,那么数据库中已存在的旧数据是未加密的明文,查询时会被当作加密数据尝试解密,从而触发填充错误。解决方式:

  • 导出所有用户数据并临时备份。
  • 将phone_number列改回普通String类型,重新导入数据。
  • 编写脚本批量加密现有数据后,再改回StringEncryptedType列类型。
  • 或直接删除旧测试数据,创建新用户测试解密是否正常。

3. 显式指定加密引擎

默认情况下StringEncryptedType使用AesEngine,但显式指定可避免潜在的配置不一致问题,修改models.py中的列定义:

from sqlalchemy_utils.types.encrypted.encrypted_type import StringEncryptedType, AesEngine

class Users(Base):
    __tablename__ = "users"

    id = Column(UUID(as_uuid=True), primary_key=True, unique=True, default=uuid.uuid4)
    username = Column(String(255), nullable=False)
    phone_number = Column(StringEncryptedType(
        String(255), 
        settings.ENCRYPT_KEY, 
        engine=AesEngine  # 显式指定加密引擎
    ), nullable=False)
    created_at = Column(DateTime, server_default=func.now())

4. 检查依赖版本兼容性

确保sqlalchemy_utils版本支持异步SQLAlchemy环境,旧版本可能存在异步场景下的加密/解密异常,执行升级命令:

pip install --upgrade sqlalchemy_utils

5. 测试新用户的加密解密流程

先调用db_create_user接口创建一个新用户,再查询/users接口,如果新用户的phone_number能正常解密,说明问题出在旧数据上,按照步骤2处理即可。

内容的提问来源于stack exchange,提问作者Riley Hun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 05:27:50