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

解密cryptography库Fernet编码PIN校验输入及TypeError报错处理

问题原因分析

报错与逻辑异常由以下错误导致:

  • 触发TypeError: token must be bytes的直接原因:使用文本模式'r'读取.key文件,获取的内容为字符串类型,但Fernet的decrypt方法要求传入的加密token必须是bytes类型。
  • 逻辑错位:已通过readlines()遍历文件内容后,文件指针已移动到末尾,后续pid_file.read()无法读取到有效内容;同时错误将fer.decrypt()的返回值作为read()的长度参数,decrypt会直接返回解密后的明文bytes,无需再调用文件读取方法。
  • 类型与逻辑错误:data.split()返回值为列表,无法直接传入decrypt方法;解密后得到的是bytes类型,调用encode()属于错误类型转换,正确操作为将bytes转为字符串后与用户输入比对。
修正后代码示例

需要使用加密PIN时相同的Fernet密钥初始化实例,不能使用新生成的密钥,示例如下:

from cryptography.fernet import Fernet

# 读取你加密时使用的Fernet密钥,替换为你实际的密钥存储路径
with open("fernet_secret.key", 'rb') as f:
    fernet_key = f.read()
fer = Fernet(fernet_key)

def get_pin():
    pid_input = input("Enter your pin :  ")
    # 用二进制模式读取加密后的PIN文件
    with open("PID.key", 'rb') as pid_file:
        encrypted_pid = pid_file.read().strip()
    try:
        # 解密后转成utf-8字符串
        decrypted_pid = fer.decrypt(encrypted_pid).decode("utf-8")
    except Exception:
        # 解密失败(密钥错误、文件被篡改等)直接退出
        exit()
    if pid_input != decrypted_pid:
        exit()
存储方案说明
  • 使用.key扩展名存储加密后的PIN本身不存在不合理问题,扩展名仅为文件标识,不影响功能实现,只要做好文件权限管控即可。
  • 注意加密用的Fernet密钥不能和加密后的PIN存储在同一位置,否则攻击者同时拿到两个文件即可直接解密获取明文PIN,失去加密意义。
  • 若PIN为短位数纯数字密码,即使加密存储也存在暴力破解风险,建议适当提升PIN复杂度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 07:54:02