I am reading in an image, encrypting it, then decrypting it. The goal is to be looping this eventually and recording the time it takes for the process to complete. Currently what I have it reads the file in, then it encrypts it, encrypts it, the creates another file based on the recovered data. I don't need to make another file with the decrypted picture. Previously I had been using StringSource
and StringSink
, but that only worked for text files. I received some help at How to read an image to a string for encrypting Crypto++ from and started using FileSink
and FileSource
.
What exactly is the difference between FileSink
, StringSink
, FileSource
and StringSource
?
Also, in following example, why does cipher need to be set to something? Previously when I was just using StringSource
, my string cipher was not initialized, but now that I am using FileSource
, it needs to be initialized for it to work.
int main(int argc, char* argv[])
{
AutoSeededRandomPool prng_blowfish;
SecByteBlock key_blowfish(Blowfish::DEFAULT_KEYLENGTH);
prng_blowfish.GenerateBlock(key_blowfish, key_blowfish.size());
byte iv_blowfish[Blowfish::BLOCKSIZE];
prng_blowfish.GenerateBlock(iv_blowfish, sizeof(iv_blowfish));
string ifilename = "sample_files/1MB.jpg";
string cipher = "1MB.enc";
string rfilename = "r1MB.jpg";
try
{
EAX<Blowfish>::Encryption e_blowfish;
e_blowfish.SetKeyWithIV(key_blowfish, key_blowfish.size(), iv_blowfish, sizeof(iv_blowfish));
std::ifstream ifile(ifilename.c_str(), ios::binary);
std::ifstream::pos_type size = ifile.seekg(0, std::ios_base::end).tellg();
ifile.seekg(0, std::ios_base::beg);
FileSource fs1(ifilename.c_str(), true, new AuthenticatedEncryptionFilter(e_blowfish, new FileSink(cipher.c_str())));
EAX<Blowfish>::Decryption d_blowfish;
d_blowfish.SetKeyWithIV(key_blowfish, key_blowfish.size(), iv_blowfish, sizeof(iv_blowfish));
FileSource fs2(cipher.c_str(), true, new AuthenticatedDecryptionFilter(d_blowfish, new FileSink(rfilename.c_str()), AuthenticatedDecryptionFilter::THROW_EXCEPTION));
}
catch (const Exception& ex)
{
cerr << ex.what() << endl;
}
return 0;
}
What exactly is the difference between FileSink, StringSink, FileSourcem StringSource.
Sources, Filters and Sinks are part of the Pipeline design in Crypto++. Data flows from a source, is transformed by filters, and then ends at a sink.
All sources are interchangeable. All filters are interchangeable. And all sinks are interchangeable. For example, to switch between a StringSink
and FileSink
, you need to supply a filename with a FileSink
. Otherwise, they operate the same. As another example, you can switch between a HexEncoder
and Base64Encoder
with no changes. As a final example, a SocketSource
or SocketSink
are going to need an IP address and port. What may (or may not) need to be changed depends on the object.
There are a number of sources. From Source Class Reference:
FileSource
StringSource
RandomNumberSource
WindowPipeSource
SocketSource
There are a number of filters. You are using two of them - AuthenticatedEncryptionFilter
and AuthenticatedDecryptionFilter
. From Filter Class Reference and FilterWithBufferedInput Class Reference:
HexEncoder
HexEncoder
Base32Encoder
Base32Decoder
Base64Encoder
Base64Encoder
DefaultEncryptor
DefaultEncryptorWithMAC
DefaultDecryptor
DefaultDecryptorWithMAC
- ...
StreamTransformationFilter
AuthenticatedEncryptionFilter
AuthenticatedDecryptionFilter
There are a number of sinks. From Sink Class Reference:
ArraySink
BitBucket
RandomNumberSink
StringSink
FileSink
SocketSink
- ...
There are some advanced topics, but I don't think they matter at the moment. For example, the role of BufferedTransformation
and what it means if Attachable
returns true
. The answer is both Filters and Sinks are BufferedTransformation
's, and Attachable = true
means its a Filter (otherwise its a Sink).
... in following example, why does cipher need to be set to something...
A StringSource
and StringSink
needs nothing because its just an array of byes in memory. A FileSource
and FileSink
needs a filename, and you are using cipher
for the filename. You have to supply a filename because the objects a file/stream related. If you were using a SocketSource
or SocketSink
, then you would need to supply an IP address and port (more correctly, a socket_t
).
Here are the FileSource
constructors from FileSource Class Reference. You are using the third constructor in your code.
FileSource (BufferedTransformation *attachment=NULL)
FileSource (std::istream &in, bool pumpAll, BufferedTransformation *attachment=NULL)
FileSource (const char *filename, bool pumpAll, BufferedTransformation *attachment=NULL, bool binary=true)
Here are the FileSink
constructors from FileSink Class Reference. You are using the second constructor in your code.
FileSink (std::ostream &out)
FileSink (const char *filename, bool binary=true)