首页 > 解决方案 > 使用 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整个文件只有一个?

标签: pythoncryptographypycryptoaes-gcmpycryptodome

解决方案


正如@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

?


推荐阅读