Verschlüsseln Sie eine große Datei, die nicht in den Arbeitsspeicher passt, mit AES-GCM
Nov 22 2020
Dieser Code funktioniert für eine Datei, myfile
die in den Arbeitsspeicher passt:
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)
Aber wie verschlüsselt man eine 64-GB-Datei mit dieser Technik?
Offensichtlich g.read(...)
sollte der eine kleinere Puffergröße verwenden, zB 128 MB.
Aber wie funktioniert es dann für den Krypto-Teil? Sollten wir (ciphertext, tag)
für jeden 128-MB-Block einen behalten ?
Oder ist es möglich, nur eine tag
für die gesamte Datei zu haben?
Antworten
Basj Nov 22 2020 at 20:30
Wie in @ PresidentJamesK.Polks Kommentar erwähnt, scheint dies die Lösung zu sein:
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
Das einzige Problem ist, dass beim Zurücklesen dieser Datei zur Entschlüsselung das Anhalten am Ende minus 16 Bytes etwas ärgerlich ist .
Oder vielleicht sollte man das machen:
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
?