python - 如何使用 Python 加密大文件?

我正在尝试加密大于 1GB 的文件。我不想把它全部读到内存中。我为此任务选择了 Fernet (cryptography.fernet),因为它是最受推荐的(比非对称解决方案更快)。

我生成了 key 。然后我创建了一个脚本来加密:

    key = Fernet(read_key())

    with open(source, "rb") as src, open(destination, "wb") as dest:
        for chunk in iter(lambda: src.read(4096), b""):
            encrypted = key.encrypt(chunk)
            dest.write(encrypted)

和解密:

    key = Fernet(read_key())

    with open(source, "rb") as src, open(destination, "wb") as dest:
        for chunk in iter(lambda: src.read(4096), b""):
            decrypted = key.decrypt(chunk)
            dest.write(decrypted)

加密有效 - 不足为奇,但解密则不然。 首先,我认为它可能会起作用,但事实并非如此。我想加密时 block 大小会增加,然后当我读取 4096 字节时,它不是一个完整的加密 block 。我在尝试解密时遇到错误:

Traceback (most recent call last):
  File "/redacted/path/venv/lib/python3.7/site-packages/cryptography/fernet.py", line 119, in _verify_signature
    h.verify(data[-32:])
  File "/redacted/path/venv/lib/python3.7/site-packages/cryptography/hazmat/primitives/hmac.py", line 74, in verify
    ctx.verify(signature)
  File "/redacted/path/venv/lib/python3.7/site-packages/cryptography/hazmat/backends/openssl/hmac.py", line 75, in verify
    raise InvalidSignature("Signature did not match digest.")
cryptography.exceptions.InvalidSignature: Signature did not match digest.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/redacted/path/main.py", line 63, in <module>
    decrypted = key.decrypt(chunk)
  File "/redacted/path/venv/lib/python3.7/site-packages/cryptography/fernet.py", line 80, in decrypt
    return self._decrypt_data(data, timestamp, time_info)
  File "/redacted/path/venv/lib/python3.7/site-packages/cryptography/fernet.py", line 137, in _decrypt_data
    self._verify_signature(data)
  File "/redacted/path/venv/lib/python3.7/site-packages/cryptography/fernet.py", line 121, in _verify_signature
    raise InvalidToken
cryptography.fernet.InvalidToken

有没有办法解决这个问题?也许有比 fernet 更好(更简单)的解决方案?

最佳答案

Fernet 不应该以流媒体方式使用。他们在文档中解释说:

From the documentation (last section):

Limitations

Fernet is ideal for encrypting data that easily fits in memory. As a design feature it does not expose unauthenticated bytes. This means that the complete message contents must be available in memory, making Fernet generally unsuitable for very large files at this time.

https://stackoverflow.com/questions/69312922/

相关文章:

javascript - 在javascript中找到嵌套数组中的最低值

python - 如何减少由许多条件语句组成的函数?

r - 如果 R 中的其他列中存在值,则用于创建 T/F 列的 dplyr 解决方案

julia - Julia 中具有评估/计算属性的结构

c++ - C++20 中的新型自动生成构造函数

node.js - Docker + WebGL + Headless Chrome 错误 : Pa

javascript - 如何使用新的 Webpack devServer 配置?

php - Shopware 6 价格收集器/处理器的折扣计算错误

rust - Vec> 按第一个元素升序排序,当第一个元素相等时按第二个元素降序排

html - 使用图像标签在网页上显示原始像素阵列