假设您正在使用加密 python 包提供的 Fernet 类,您需要encode您的密钥作为 base64 在传入之前不会对其进行解码。编码转换为指定的形式,解码从指定的形式转换。您当前正在做的事情是转换exit_care
转换为 ascii(不必要),计算 md5 哈希值,获取十六进制表示形式,然后再次将其转换为 ascii。然后,当您使用时,您的程序会尝试将十六进制->ascii md5哈希解释为base64编码的字符串base64.urlsafe_b64decode(key)
。这是目前的失败点。可能你想使用base64.urlsafe_b64encode(key)
而是将其转换为使用 Fernet 所需的 base64。
这是可能的您可能需要将其填充到 32 字节正如 Fernet 文档所示https://cryptography.io/en/latest/fernet/#cryptography.fernet.Fernet https://cryptography.io/en/latest/fernet/#cryptography.fernet.Fernet
参数: key (bytes) – URL 安全的 base64 编码的 32 字节密钥。这必须保密。拥有此密钥的任何人都可以创建和阅读消息。
这是因为 MD5 将生成一个 128 位值,该值被编码为 22 个字符的 base64 字符串(实际上是 24,因为 python 自动填充为 4 的倍数)。看https://stackoverflow.com/a/13296298/6269138 https://stackoverflow.com/a/13296298/6269138至于为什么会这样。查看 Fernet 实现,他们检查 64 位编码字符串的长度以查看其长度是否为 32,如果不是,则会出错。你可以右垫=
如果需要,或者您可以使用下面描述的密钥生成/密钥拉伸算法。
我建议使用与此处找到的密码学 python 包的 Fernet 文档类似的设置https://cryptography.io/en/latest/fernet/#using-passwords-with-fernet https://cryptography.io/en/latest/fernet/#using-passwords-with-fernet用于键拉伸。该页面中的代码粘贴在下面,用 HKDF 替换 PBKDF2HMAC,因为前者需要盐,并且只要您不将密码存储在生产数据库上,对于这种情况可能就有点过分了。
>>> import base64
>>> import os
>>> from cryptography.fernet import Fernet
>>> from cryptography.hazmat.backends import default_backend
>>> from cryptography.hazmat.primitives import hashes
>>> from cryptography.hazmat.primitives.kdf.hkdf import HKDF
>>> password = b"password"
>>> hkdf = HKDF(
... algorithm=hashes.SHA256(), # You can swap this out for hashes.MD5()
... length=32,
... salt=None, # You may be able to remove this line but I'm unable to test
... info=None, # You may also be able to remove this line
... backend=default_backend()
... )
>>> key = base64.urlsafe_b64encode(hkdf.derive(password))
>>> f = Fernet(key)
>>> token = f.encrypt(b"Secret message!")
>>> token
b'...'
>>> f.decrypt(token) # Process the key in the exact same manner to decode an encoded message
b'Secret message!'