title: Is this AES GCM file encryption good practice?
body: <p>I'm using this to encrypt a file, and then to decrypt a file, using AES-GCM:</p>
  <p>(do <code>pip install pycryptodome</code> first if not installed yet)</p>
  <pre><code>import Crypto.Random, Crypto.Protocol.KDF, Crypto.Cipher.AES
  
  def cipherAES_GCM(pwd, nonce):
      key = Crypto.Protocol.KDF.PBKDF2(pwd, nonce, count=100_000)
      return Crypto.Cipher.AES.new(key, Crypto.Cipher.AES.MODE_GCM, nonce=nonce)    
  
  # encrypt
  plaintext = b'HelloHelloHelloHelloHelloHelloHello'  # in reality, read from a file
  key = b'mykey'
  nonce = Crypto.Random.new().read(16)
  c, tag = cipherAES_GCM(key, nonce).encrypt_and_digest(plaintext)
  ciphertext = nonce + tag + c     # write ciphertext to disk as the &quot;encrypted file&quot;
  
  # decrypt
  nonce, tag, c = ciphertext[:16], ciphertext[16:32], ciphertext[32:]  # read from the &quot;encrypted file&quot; on disk
  plain = cipherAES_GCM(key, nonce).decrypt_and_verify(c, tag).decode()
  print(plain)  # HelloHelloHelloHelloHelloHelloHello
  </code></pre>
  <p><strong>Is this considered a good encryption practice, and what the potential weaknesses of this file encryption implementation?</strong></p>
  <hr />
  <p>Remark: I have 10,000 files to encrypt. If each single time I encrypt a file, I call the KDF (with a high <code>count</code> value), this will be highly unefficient!<br />
  A better solution would be: call the KDF only once (with a <code>nonce1</code>), and then for each file do:</p>
  <pre><code>nonce2 = Crypto.Random.new().read(16)
  cipher, tag = AES.new(key, AES.MODE_GCM, nonce=nonce2).encrypt_and_digest(plain)
  </code></pre>
  <p>But then does this mean I have to write <code>nonce1 | nonce2 | ciphertext | tag</code> to disk for each file? This adds an additional 16-byte <code>nonce1</code> to each file...</p>