我正在尝试加密大于 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/