Fernet 密钥必须是 32 个 url 安全的 base64 编码字节 - 如何创建与 Fernet 一起使用的密钥?

问题描述 投票:0回答:1

Fernet 密钥示例

以下代码生成示例 Fernet 密钥,并报告长度为 44。

from cryptography.fernet import Fernet

generated_key = Fernet.generate_key()
print(f'Example generated key: {generated_key}')
print(f'Length of example key: {len(generated_key)}')

输出是(例如)

Example generated key: b'U4f1fCfXWlz7pQ-7WdZKmCY-VtSAln7R-hhvF6qgYa4='
Length of example key: 44

快速浏览一下这个参考文献告诉我们,

=
是一个填充字符。如果不包括这个
=
符号,实际上有 43 个字符。

U4f1fCfXWlz7pQ-7WdZKmCY-VtSAln7R-hhvF6qgYa4

1    2    3    4    5    6    7    8    9    10   11
U4f1 fCfX Wlz7 pQ-7 WdZK mCY- VtSA ln7R -hhv F6qg Ya4

即 10 个 4 个字符的块加上 3 个字符 = 43。

生成示例 Fernet 密钥

我正在尝试使用以下代码生成示例密钥:

key = "1234567890123456789012345678901234567890"
print(f'Encryption key is: {key}')

base64_key = base64.b64encode(key.encode('utf-8'))
print(f'Base64 encoded key is: {base64_key}')
print(f'Length of base64 encoded key: {len(base64_key)}')

if len(base64_key) > 43:
    base64_key = base64_key[:43]
    print(f'Truncating key to length {43}: {base64_key}')
    print(f'Length of base64 encoded key is now {len(base64_key)}')
elif len(base64_key) < required_key_length_characters:
    print(f'error: key is too short')
    raise RuntimeError(f'key too short')

fernet_instance = Fernet(base64_key)

但是这会产生以下输出和异常:

Encryption key is: 1234567890123456789012345678901234567890
Base64 encoded key is: b'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MA=='
Length of base64 encoded key: 56
Truncating key to length 43: b'MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI'
Length of base64 encoded key is now 43

binascii.Error: Incorrect padding

确实,手动破解填充

base64_key = base64_key + b'='

解决了问题。

Fernet 密钥应该多长?

我的代码产生的异常表示

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

32 字节 = 256 位。每个base64编码的字符是6位。

256 / 6 = 42.6666...或 43(如果四舍五入的话)。这与

Fernet.generate_key()
生成的密钥长度相匹配。

为什么钥匙太短就不起作用?

43 个字符的密钥包含足够的位来进行 256 位的加密。那么为什么这不起作用呢?

它实际上有略多于 256 位的信息。 43 * 6 = 258

如果密钥长度完全正确,为什么不起作用?

44 个字符的密钥包含足够的位来进行 256 位的加密,并且它与 4 字节边界对齐。但是,它仍然失败并产生以下异常:

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

因此,即使 4 字节边界是一些奇怪的任意要求(也许是一个错误?),那么这应该可以工作,特别是考虑到长度为 43 的密钥并不具有正好 256 位的信息。有258个。

如果密钥太长则不起作用

鉴于上述情况,这并不奇怪。

如果您根本不截断密钥,则会产生相同的异常。

那么生成这个密钥的正确方法是什么?

截断到 43 个字符,然后在末尾添加填充字符以将长度增加到 44 的逻辑似乎是任意的。

有没有更好的方法使用密码样式输入来生成这种密钥?

python cryptography base64 fernet
1个回答
0
投票

一种方便的方法是使用固定长度哈希算法(例如 sha256)对密码进行哈希处理。我稍后会添加确切的代码。

© www.soinside.com 2019 - 2024. All rights reserved.