python - 使用 AES-GCM 加密不适合 RAM 的大文件
问题描述
此代码适用于myfile
适合 RAM 的文件:
import Crypto.Random, Crypto.Cipher.AES # pip install pycryptodome
nonce = Crypto.Random.new().read(16)
key = Crypto.Random.new().read(16) # in reality, use a key derivation function, etc. ouf of topic here
cipher = Crypto.Cipher.AES.new(key, Crypto.Cipher.AES.MODE_GCM, nonce=nonce)
out = io.BytesIO()
with open('myfile', 'rb') as g:
s = g.read()
ciphertext, tag = cipher.encrypt_and_digest(s)
out.write(nonce)
out.write(ciphertext)
out.write(tag)
但是如何使用这种技术加密一个 64 GB 的文件呢?
显然,g.read(...)
应该使用较小的缓冲区大小,例如 128 MB。
但是,它对加密部分是如何工作的?我们应该(ciphertext, tag)
为每个 128 MB 的块保留一个吗?
或者是否有可能tag
整个文件只有一个?
解决方案
正如@PresidentJamesK.Polk 的评论中提到的,这似乎是解决方案:
out.write(nonce)
while True:
block = g.read(65536)
if not block:
break
out.write(cipher.encrypt(block))
out.write(cipher.digest()) # 16-byte tag at the end of the file
唯一的问题是,当读回这个文件进行解密时,在结尾处停止负 16 个字节有点烦人。
或者也许应该这样做:
out.write(nonce)
out.seek(16, 1) # go forward of 16 bytes, placeholder for tag
while True:
...
...
out.seek(16)
out.write(cipher.digest()) # write the tag at offset #16 of the output file
?
推荐阅读
- jsp - JSTL fmt:formatDate with locale dependent pattern
- .htaccess - 使用 .htaccess 隐藏子文件夹
- docker - Awslogs 日志记录驱动程序问题 - NoCredentialProviders:链中没有有效的提供程序
- angular - 角材料垫选择样式问题
- python - How can I read the code from a text file to a dictionary in a python file?
- swift - 用于 UI 更新的领域集合插入
- javascript - 来自 REST API 的 Aurelia 动态路由
- r - 使用 R 绘制时间序列中的观察值
- node.js - 获取有关 App Engine 资源的 IAM 政策
- python - 如何将函数传递给要设置为类变量的类?我收到“不可调用”错误