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< HMAC< 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:
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<SHA256> kdf;
kdf.DeriveKey(
derived.data(),
derived.size(),
0,
(byte*)password.data(),
password.size(),
salt.data(),
salt.size(),
iterations);
// Key the cipher
GCM<AES>::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<AES>::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));
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 How to use a custom key in Crypto++. Is this good practice in cryptography? Or should I generate a separate IV every time I encrypt?
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?