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

Django中Fernet解密消息触发Invalid Token错误的原因及解决

问题分析与解决方案
  • 核心问题:密钥配置完全错误
    你在序列化器的__init__方法里,把字符串"key_generated_by_fernet.generate_key()"当成了Fernet密钥,这根本不是符合要求的有效密钥。Fernet要求密钥必须是通过Fernet.generate_key()生成的URL-safe base64编码字节串,同时你调用了load_dotenv()但并未实际从环境变量读取密钥,等于无效操作。

  • 修复步骤

    1. 生成合法Fernet密钥
      打开Python交互shell,执行以下代码生成有效密钥:

      from cryptography.fernet import Fernet
      print(Fernet.generate_key().decode())
      

      将输出的字符串复制到你的.env配置文件中,格式如下:

      ENCRYPTION_KEY=生成的密钥字符串
      
    2. 修正密钥加载逻辑
      修改序列化器的__init__方法,正确从环境变量读取密钥:

      import os
      from cryptography.fernet import Fernet, InvalidToken
      from dotenv import load_dotenv
      
      class MessageSerializer(serializers.ModelSerializer):
          created_by = BasicUserSerializer(read_only=True)
      
          class Meta:
              model = Message
              fields = '__all__'
      
          def __init__(self, *args, **kwargs):
              super().__init__(*args, **kwargs)
              load_dotenv()
              # 从环境变量读取密钥并转为字节串
              self.ENCRYPTION_KEY = os.getenv("ENCRYPTION_KEY").encode()
              self.fernet = Fernet(self.ENCRYPTION_KEY)
      
          def to_representation(self, instance):
              representation = super().to_representation(instance)
              representation['text'] = self.decrypt(instance.text)
              return representation
      
          def encrypt(self, message):
              encoded_message = message.encode()
              encrypted_message = self.fernet.encrypt(encoded_message)
              return encrypted_message
      
          def decrypt(self, encrypted_message):
              try:
                  decrypted_message = self.fernet.decrypt(encrypted_message)
                  decoded_message = decrypted_message.decode()
                  return decoded_message
              except InvalidToken:
                  raise ValueError("The encrypted message is invalid and cannot be decrypted.")
      
    3. 清理无效加密数据
      如果你之前已经用错误密钥加密过消息,这些数据无法用正确密钥解密,需要重新加密或直接删除。

  • 额外注意事项

    • 密钥必须严格保密,禁止硬编码到代码中,也不能提交到版本控制系统。
    • 应用启动后必须始终使用同一密钥,否则历史加密数据会全部无法解密。
    • 确认数据库中instance.text存储的是Fernet加密后的字节串(或可正确转为字节串的字符串),格式错误也会触发InvalidToken异常。

内容的提问来源于stack exchange,提问作者Jakub Jordanek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 04:50:12