使用AES-GCM加密不适合RAM的大文件 [英] Encrypt a big file that does not fit in RAM with AES-GCM

查看:103
本文介绍了使用AES-GCM加密不适合RAM的大文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此代码适用于RAM中适合的文件 myfile :

This code works for a file myfile which fits in 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的文件?

But how to encrypt a 64 GB file using this technique?

很显然, g.read(...)应该使用较小的缓冲区大小,例如128 MB.

Obviously, the g.read(...) should use a smaller buffer-size, e.g. 128 MB.

但是,对于加密部分它是如何工作的呢?我们是否应该为每个128 MB的块保留一个(密文,标记)?

But then, how does it work for the crypto part? Should we keep a (ciphertext, tag) for each 128-MB chunk?

或者整个文件可能只有一个 tag ?

Or is it possible to have only one tag for the whole file?

推荐答案

如@ PresidentJamesK.Polk的评论中所述,这似乎是解决方案:

As mentioned in @PresidentJamesK.Polk's comment, this seems to be the solution:

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

唯一的问题是,当读回此文件进行解密时,

The only problem is that, when reading back this file for decryption, stopping at the end minus 16 bytes is a bit annoying.

或者也许应该这样做:

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

?

这篇关于使用AES-GCM加密不适合RAM的大文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆