python:无效的base64编码字符串:数据字符数(5)不能多于4的倍数1

标签 python decode

输出以下错误:

Exception Value:
Invalid base64-encoded string: number of data characters (5) cannot be 1 more than a multiple of 4
Exception Location: D:\Program Files\Python\lib\base64.py in b64decode, line 87 "

我这样输入python:

key = hashlib.md5("exit_care".encode("ascii")).hexdigest().encode("ascii")
key_64 = base64.urlsafe_b64decode(key)
cipher_suite = Fernet(key_64)  

最佳答案

假设您使用的是加密Python包提供的Fernet类,您需要将 key 编码为base64,而不是在传入之前对其进行解码。编码转换为指定的形式,解码从指定的形式进行转换。您当前正在执行的操作是将 exit_care 转换为 ascii(不必要),计算 md5 哈希值,获取十六进制表示形式,然后将其转换为 ascii再次。然后,当您使用base64.urlsafe_b64decode(key)时,您的程序会尝试将十六进制->ascii md5哈希解释为base64编码的字符串。这是目前的失败点。您可能打算使用 base64.urlsafe_b64encode(key) 将其转换为使用 Fernet 所需的 base64。

有可能您可能需要将其填充到 32 字节,正如 Fernet 文档建议的 https://cryptography.io/en/latest/fernet/#cryptography.fernet.Fernet

Parameters: key (bytes) – A URL-safe base64-encoded 32-byte key. This must be kept secret. Anyone with this key is able to create and read messages.

这是因为 MD5 将生成一个 128 位值,该值被编码为 22 个字符的 base64 字符串(实际上是 24,因为 python 自动填充为 4 的倍数)。请参阅https://stackoverflow.com/a/13296298/6269138至于为什么会这样。查看 Fernet 实现,他们检查 64 位编码字符串的长度以查看其长度是否为 32,如果不是,则会出错。 如果需要,您可以使用 = 进行右填充,也可以使用下面描述的 key 生成/ key 拉伸(stretch)算法。

我建议使用与密码学 python 包的 Fernet 文档中类似的设置 https://cryptography.io/en/latest/fernet/#using-passwords-with-fernet用于键拉伸(stretch)。该页面中的代码粘贴在下面,用 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!'

关于python:无效的base64编码字符串:数据字符数(5)不能多于4的倍数1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55105045/

相关文章:

python - 与等待并行运行方法

python - 使用枚举定义 Python 类

python - 从 2 个摄像头捕获(OpenCV、Python)

python - matplotlib navtoolbar 在 wx 2.9 (Mac OS X) 中没有实现

java - C# 和 Java 的 URL 解码区别

python - 为什么我的 except 子句从未捕获到 gevent 超时异常?

python - Base64解码直到没有Base64

android - 使用 android MediaCodec api 压缩视频

java - 无法将 BASE64 解码为 Selenium 2 中的图像文件

java - 在 Java 中解码 "quoted-printable"字符串