如何使用 AES 256 实现 Fernet 加密

How to implement Fernet encryption with AES 256

我目前正在使用 Fernet 使用 AES 128 密钥的加密。但是我的客户要求使用 AES 256。我对密码学不是很熟悉,但这是我目前所了解的。

Fernet 需要一个分成两半的 256 位密钥。前半部分是签名密钥,后半部分是加密密钥。因为它们是 128 位长,所以是 AES 128。

将输入密钥加倍并像下面这样修改实现以获得 AES 256 是否足够?

class Fernet(object):
    def __init__(self, key, backend=None):
        if backend is None:
            backend = default_backend()

        key = base64.urlsafe_b64decode(key) # Here 512 bits long instead of 256

        self._signing_key = key[:16] # double this
        self._encryption_key = key[16:] # double this
        self._backend = backend

是的,您可以将二进制输入加倍,密钥之前的输入是 base 64 编码的。结果是否是 256 位安全取决于 密钥是如何生成的 。所以是的,可以将密钥上的 check 大小加倍,但这并不能说明什么。如果输入密钥 material 是 512 位,安全级别是 512 位那么是,然后拆分密钥就可以了。

我个人建议(我过去曾向 Fernet 推荐过)使用 HKDF 来派生两个密钥,而不是将密钥一分为二。我看不到密钥是如何生成的,但如果它是由 PBKDF2 生成的——Fernet 确实使用它从密码创建密钥——那么 PBKDF2 可能需要两倍的工作量来生成 512 位,而攻击者只需要生成 256执行攻击的位(因此执行一半的工作)。

请注意,使用 base64 编码对于键来说不是很好,因为在大多数运行时字符串很难从内存中删除;如果密钥存储在 key store.

中会更好

Fernet Specification is to use AES-128. If you modify the algorithm to use AES-256, then you would no longer be using Fernet。如果要求您同时使用 Fernet 和 AES-256,我建议您使用 AES-256 独立加密您的有效负载,然后将 Fernet 算法应用于结果。这实质上是使用 AES-128 再次对其进行加密。