Use a FileSource
and FileSink
. It avoids reading the data into an intermediate object like a string
, but its probably a little more efficient under some cases.
AutoSeededRandomPool prng;
SecByteBlock key(Blowfish::DEFAULT_KEYLENGTH);
prng.GenerateBlock( key, key.size() );
byte iv[ Blowfish::BLOCKSIZE ];
prng.GenerateBlock( iv, sizeof(iv) );
string ofilename = "puppy-and-teddy-orig.jpg";
string efilename = "puppy-and-teddy.enc";
string rfilename = "puppy-and-teddy-recovered.jpg";
try {
/*********************************\
\*********************************/
EAX< Blowfish >::Encryption e1;
e1.SetKeyWithIV(key, key.size(), iv, sizeof(iv));
FileSource fs1(ofilename.c_str(), true,
new AuthenticatedEncryptionFilter(e1,
new FileSink(efilename.c_str())
) );
/*********************************\
\*********************************/
EAX< Blowfish >::Decryption d2;
d2.SetKeyWithIV( key, key.size(), iv, sizeof(iv) );
FileSource fs2(efilename.c_str(), true,
new AuthenticatedDecryptionFilter( d2,
new FileSink( rfilename.c_str() ),
AuthenticatedDecryptionFilter::THROW_EXCEPTION
) );
} catch (const Exception& ex) {
cerr << ex.what() << endl;
}
Here's the image:
Here's the encrypted image under a hex editor:
Running it produces no difference between the original and recovered images:
$ ./cryptopp-test.exe
$ diff puppy-and-teddy-orig.jpg puppy-and-teddy-recovered.jpg
$
If you really want to read it into a string, here are the relevant changes:
std::ifstream ifile("puppy-and-teddy-orig.jpg", ios::binary);
std::ifstream::pos_type size = ifile.seekg(0, std::ios_base::end).tellg();
ifile.seekg(0, std::ios_base::beg);
string temp;
temp.resize(size);
ifile.read((char*)temp.data(), temp.size());
/*********************************\
\*********************************/
EAX< Blowfish >::Encryption e1;
e1.SetKeyWithIV(key, key.size(), iv, sizeof(iv));
StringSource ss1(temp, true,
new AuthenticatedEncryptionFilter( e1,
new FileSink(efilename.c_str())
) );
/*********************************\
\*********************************/
EAX< Blowfish >::Decryption d2;
d2.SetKeyWithIV( key, key.size(), iv, sizeof(iv) );
FileSource fs2(efilename.c_str(), true,
new AuthenticatedDecryptionFilter(d2,
new FileSink(rfilename.c_str()),
AuthenticatedDecryptionFilter::THROW_EXCEPTION
) );