我一直在尝试使用Crypto ++在GCM模式下使用AES加密和解密文件。该代码应该做的是,给定密码,使用PBKDF2< HMAC< SHA256>>,然后使用密码哈希作为密钥加密和解密文件。在Stack Overflow上搜索完毕后,我已经做到了这一点:
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));
如果使用来自PBKDF2的一半派生哈希作为密钥而一半使用IV似乎很奇怪,则此代码主要从How to use a custom key in Crypto++复制。这是密码学的好习惯吗?或者我应该在每次加密时生成一个单独的IV?
Crypto ++会抛出HashVerificationFailed异常,这意味着自加密以来数据已更改。显然我做错了什么。我的代码出了什么问题?