title: Properly Decrypt AES in GCM mode in Crypto++
body: <p>I've been trying to encrypt and decrypt a file using AES in GCM mode using Crypto++. What this code is supposed to do is, given a password, hash it using PBKDF2&lt; HMAC&lt; SHA256>>, then encrypt and decrypt a file using the password hash as the key. After searching all over on Stack Overflow I've gotten this far:</p>
  
  <pre><code>using namespace Cryptopp;
  
  const std::string password = "password";
  const int iterations = 1000000;
  const std::string fileName = "test.txt";
  SecByteBlock derived(32);
  SecByteBlock salt(16);
  const int TAG_SIZE = AES::BLOCKSIZE;
  
  AutoSeededRandomPool rng;
  rng.GenerateBlock(salt, 16);
  
  // KDF function
  PKCS5_PBKDF2_HMAC&lt;SHA256&gt; kdf;
  kdf.DeriveKey(
      derived.data(), 
      derived.size(), 
      0, 
      (byte*)password.data(), 
      password.size(), 
      salt.data(), 
      salt.size(), 
      iterations);
  
  // Key the cipher
  GCM&lt;AES&gt;::Encryption encryptor;
  encryptor.SetKeyWithIV(derived.data(), 16, derived.data() + 16, 16);
  
  FileSource(fileName.c_str(), true,
      new AuthenticatedEncryptionFilter(encryptor, 
      new FileSink(fileName.c_str()), false, TAG_SIZE));
  
  // Key the cipher
  GCM&lt;AES&gt;::Decryption decryptor;
  decryptor.SetKeyWithIV(derived.data(), 16, derived.data() + 16, 16);
  
  AuthenticatedDecryptionFilter decryptionFilter(decryptor, 
      new FileSink(fileName.c_str()), 16, TAG_SIZE);
  FileSource(fileName.c_str(), true, new Redirector(decryptionFilter));
  </code></pre>
  
  <p>If the use of half of the derived hash from PBKDF2 as the key and half as the IV seems weird, this code is largely copied from <a href="https://stackoverflow.com/questions/27342535/how-to-use-a-custom-key-in-crypto">How to use a custom key in Crypto++</a>. Is this good practice in cryptography? Or should I generate a separate IV every time I encrypt?</p>
  
  <p>Crypto++ throws a HashVerificationFailed exception, meaning the data was changed since encryption. So obviously I'm doing something wrong. What's wrong with my code?</p>