Reputation: 1
I am working on a project that includes encrypting and decrypting files, I process the file and then I encrypt it and save it on a new file with a custom file extension, the file includes the encrypted file bytes and the IV used during encryption, like this: IV#fileBytes. When decrypting the file I encounter the problem "invalid PKCS #7 block padding found in file decryption". I will really appreciate some help, Thank you!
void encryptFile(const byte* AESkey, const std::string& path)
{
std::ifstream binaryFile;
std::ofstream encryptedFile;
std::string encryptedDataBinary;
binaryFile.open(path, std::ios::binary);
encryptedFile.open(path + ".lok", std::ios::binary);
// Initialize with a random IV
CryptoPP::SecByteBlock iv(CryptoPP::AES::BLOCKSIZE);
CryptoPP::AutoSeededRandomPool prng;
prng.GenerateBlock(iv, iv.size());
// Write the IV as raw bytes to the beginning of the encrypted file
encryptedFile.write(reinterpret_cast<const char*>(iv.data()), iv.size());
encryptedFile << '#'; // Add the separator
// Create AES encryption object
CryptoPP::CBC_Mode< CryptoPP::AES >::Encryption e;
e.SetKeyWithIV(AESkey, CryptoPP::AES::DEFAULT_KEYLENGTH, iv);
// Read the entire file
std::string inputData(
(std::istreambuf_iterator<char>(binaryFile)),
std::istreambuf_iterator<char>()
);
// Encrypt the data
// The StreamTransformationFilter adds padding
// as required. ECB and CBC Mode must be padded
// to the block size of the cipher.
CryptoPP::StringSource(inputData, true, new CryptoPP::StreamTransformationFilter(e, new CryptoPP::StringSink(encryptedDataBinary)));
encryptedFile << encryptedDataBinary;
// Close the files
binaryFile.close();
encryptedFile.close();
std::remove(path.c_str());`
}
void decryptFile(const byte* AESkey, std::string& path)
{
std::string decrypted;
CryptoPP::SecByteBlock iv(CryptoPP::AES::BLOCKSIZE);
std::fstream decryptedFile;
std::ifstream encryptedFile;
std::stringstream inputData;
decryptedFile.open(revertFileExtension(path), std::ios::binary);
encryptedFile.open(path);
// Read the IV from the beginning of the encrypted file
encryptedFile.read(reinterpret_cast<char*>(iv.data()), iv.size());
encryptedFile.rdstate();
// Skip the "#" separator
char separator;
encryptedFile.read(&separator, 1);
// Process the rest of the file (excluding the IV and separator)
inputData << encryptedFile.rdbuf();
//decoding hex data to just aes encrypted
//decrypting aes
CryptoPP::CBC_Mode< CryptoPP::AES >::Decryption d;
d.SetKeyWithIV(AESkey, CryptoPP::AES::DEFAULT_KEYLENGTH, iv);
// The StreamTransformationFilter removes
//padding as required.
CryptoPP::StringSource ssd(inputData.str(), true, new CryptoPP::StreamTransformationFilter(d, new CryptoPP::StringSink(decrypted)));
decryptedFile << decrypted;
// Close the files
encryptedFile.close();
decryptedFile.close();
// Remove the original encrypted file
std::remove(path.c_str());`
}
I tested the code on .txt files, I checked the key the IV and the encrypted file bytes and didn't notice any change that was caused because of saving them on the new file.
Upvotes: 0
Views: 161