使用短PIN/密钥加密主密码遇Fernet密钥格式错误求助
解决Fernet密钥格式错误问题
你的代码触发错误的核心原因是生成的密钥完全不符合Fernet的要求——Fernet必须接收经过URL安全Base64编码的32字节原始数据,你的处理流程踩了三个坑:
- 用
hexdigest()把SHA256哈希转换成64字符的十六进制字符串,这不是Base64编码格式; - 调用
key.decode()属于错误操作:decode()是把字节转成字符串,但你这里的key本身就是字符串,完全没必要; - 即使截取后的字符串转成字节,长度也不是32字节,不满足Fernet的密钥长度要求。
正确实现代码
从短PIN生成合规Fernet密钥的正确步骤:
- 将PIN编码为字节;
- 用SHA256哈希得到32字节的原始哈希值(用
digest()而非hexdigest()); - 将这32字节转换为URL安全的Base64编码字符串。
修正后的代码示例:
import hashlib import base64 from cryptography.fernet import Fernet pin = self.pin_ent.get() # 生成32字节的SHA256原始哈希数据 raw_hash = hashlib.sha256(pin.encode()).digest() # 转换为Fernet要求的URL安全Base64编码格式 fernet_key = base64.urlsafe_b64encode(raw_hash) # 初始化Fernet实例 f = Fernet(fernet_key)
关键细节说明
digest()vshexdigest():digest()返回的是原始字节序列(正好32字节),符合Fernet对密钥原始长度的要求;hexdigest()是把字节转成十六进制字符串,长度翻倍为64字符,完全没必要。- URL安全Base64编码:Fernet要求密钥必须用这种编码,它会替换掉普通Base64中的
+和/为-和_,避免在传输或存储时出现格式问题。
内容的提问来源于stack exchange,提问作者Paweł Pietraszko
相关产品推荐
相关产品推荐

