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

Fernet密钥格式错误求助:Django解密时提示需32位URL安全Base64字节

解决Fernet解密时的ValueError: Fernet key must be 32 url-safe base64-encoded bytes错误

问题场景

在Django项目中解密经Fernet加密的内容时,持续触发错误:

ValueError at / Fernet key must be 32 url-safe base64-encoded bytes

密钥通过Django模板的输入框传入,获取输入值后用于解密时始终报错。

相关代码

Django模板代码

<form action="" method="POST" enctype="multipart/form-data">
     {% csrf_token %}
        <h3>Welcome to Encryption, Decryption and Compression program using Python</h3>
         {% for field in form %}
           <div>{{ field }} </div>
                {% endfor  %}
                  <select name="choices" id="choices">
                     <option>Encryption</option>
                     <option>Decryption</option>
                      <option>Encryption and Compression</option>
                      <option>Decryption and Compression</option>
                      <option>Compression</option>
                   </select>
                 <input type="text" name="dkey" id="dkey" placeholder="Enter Decryption Key">
 
                        <button >Proceed</button>
                    </form>

views.py代码(原错误版本)

def decryption(self, key):
        key = base64.urlsafe_b64encode(bytes(key, encoding="utf-8"))
        f = Fernet(key)

def post(self, request):
        m_file = request.FILES['file']
        opt = request.POST.get('choices')
        if opt == "Decryption":
            dkey = request.POST.get('dkey')
            decrypted = self.decryption(dkey)

加密方法代码

def encryption(self, content):
    key = Fernet.generate_key()
    cipher_suite = Fernet(key)
    cipher_text = cipher_suite.encrypt(bytes(str(content), encoding='utf-8'))
     return cipher_text, key

用户输入的Fernet密钥

Pl85l36CA7TJe48jv8nWYFD4SWIhIJNFQL8CyyLlXR4=

错误原因

加密时Fernet.generate_key()生成的密钥已经是URL-safe的base64编码字节串,用户输入的密钥就是该字节串解码后的字符串。但当前decryption方法中,对用户输入的密钥做了多余的base64二次编码,导致密钥长度远超Fernet要求的32字节,触发了ValueError。

修复方案

  1. 移除decryption方法中多余的base64.urlsafe_b64encode操作,直接将用户输入的密钥字符串转为字节。
  2. 增加输入清洗,去除密钥可能带有的多余字符(比如示例中的**)。

修复后的代码

views.py修改后

import base64
from cryptography.fernet import Fernet

def decryption(self, key, encrypted_data):
        # 清洗输入:去除首尾多余字符(如空格、**)
        cleaned_key = key.strip().strip('*')
        # 直接转成字节,无需二次编码
        key_bytes = bytes(cleaned_key, encoding="utf-8")
        f = Fernet(key_bytes)
        # 补充解密逻辑
        decrypted_data = f.decrypt(encrypted_data)
        return decrypted_data

def post(self, request):
        m_file = request.FILES['file']
        opt = request.POST.get('choices')
        if opt == "Decryption":
            dkey = request.POST.get('dkey')
            if dkey:
                # 读取上传文件中的加密内容
                encrypted_data = m_file.read()
                decrypted = self.decryption(dkey, encrypted_data)
            else:
                # 处理密钥为空的情况
                pass

额外注意事项

  • 确保用户输入的密钥与加密时生成的密钥完全一致,避免输入错误(如大小写、多余空格)。
  • 原decryption方法缺失实际的解密逻辑(读取加密内容、调用decrypt方法),需补充完整才能完成解密流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 13:15:32