1

I need to read a file as binary data, then be able encrypt and decrypt it. I am testing speeds of different algorithms in Crypto++. Up until now, I have been using getline to read text files.

int main( int argc, char* argv[] ) {
string plaintext, ciphertext, encoded, recovered, sample_files_path, data_file, line_contents, file_size; 

ifstream initial_file_contents ( "1MB.txt");
if (initial_file_contents.is_open()) {
    plaintext = "";
    while ( getline( initial_file_contents, line_contents ) ) {
        plaintext = plaintext + line_contents;
        plaintext.push_back('\n');
        initial_file_contents.close();
    }
} else {
    cout << "Unable to open file" << endl;
}

/*BLOWFISH ALGORITHM*/
AutoSeededRandomPool blowfish_prng; // This class seeds itself using an operating system provided RNG
SecByteBlock blowfish_key(Blowfish::DEFAULT_KEYLENGTH); // Generate a random key
blowfish_prng.GenerateBlock(blowfish_key, blowfish_key.size()); // Generate a random initialization vector
byte blowfish_iv[Blowfish::BLOCKSIZE];
blowfish_prng.GenerateBlock(blowfish_iv, sizeof(blowfish_iv));

// Encrypts the plaintext
e.SetKeyWithIV( blowfish_key, blowfish_key.size(), blowfish_iv, sizeof(blowfish_iv) );
ciphertext.clear();
StringSource ss1(plaintext, true, new AuthenticatedEncryptionFilter( e, new StringSink( ciphertext ) )  ); 

// Decrypts the test
EAX< Blowfish >::Decryption d;
d.SetKeyWithIV( blowfish_key, blowfish_key.size(), blowfish_iv, sizeof(blowfish_iv) );
recovered.clear();
StringSource ss2(ciphertext, true, new AuthenticatedDecryptionFilter( d, new StringSink( recovered ), AuthenticatedDecryptionFilter::THROW_EXCEPTION ) ); 
return 0;
}

I have seen other articles like Reading an image file in C/C++ and Read a binary file (jpg) to a string using c++ , but I am unsure how to do it. I feel like http://www.cplusplus.com/reference/istream/istream/read/ might be a good example, but I am still unsure how to implement it. Can someone show me how to read in a file such as a .jpg file, and store it as a string so I can encrypt it?

If I had a file named image.jpg, how would I read it in to be in a string variable like plaintext?

Community
  • 1
  • 1
j.atec
  • 349
  • 2
  • 16
  • "Can someone show me how to do this?" - How to do what? – jww Apr 29 '14 at 03:30
  • @jww I need to read different file types into a string so I can encrypt it. – j.atec Apr 29 '14 at 03:40
  • 1
    But you are reading files now, no? If you want to do binary, then use `ios::binary` flag. Or use a Crypto++ `FileSink` and `FileSource`. They are set up for binary out of the box, and don't require extra flags like C++ `istreams` and `ostreams`. – jww Apr 29 '14 at 03:47
  • 1
    `getline` will convert end of lines, so what you read is not necessarily what's in the file on disk. If you are going to open the stream, you should do so with `ios::binary` and use [`istream::read`](http://www.cplusplus.com/reference/istream/istream/read/) to avoid the conversions. – jww Apr 29 '14 at 03:54
  • @jww Yes, I would like if someone would show how to do that, because I am still a little lost and new to C++. – j.atec Apr 29 '14 at 03:58
  • btw there is a benchmark in crypto++ library sources – Maciej S Apr 29 '14 at 20:06

1 Answers1

1

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:

enter image description here

Here's the encrypted image under a hex editor:

enter image description here

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
               ) );
jww
  • 83,594
  • 69
  • 338
  • 732
  • Cannot get either of these to work. Probably because I don't know C++ very well. Even when I say using CryptoPP::FileSource, it still says, "encryption_tests.cpp:168:7: error: ‘FileSource’ was not declared in this scope". I according to the manual, it is in filter.h... – j.atec Apr 29 '14 at 06:24
  • `#include `. http://www.cryptopp.com/docs/ref/files_8h_source.html. – jww Apr 29 '14 at 06:37
  • Any way you could post the whole program with all includes? If I could run it, then I would be able to figure out what I am missing exactly. Thanks! – j.atec Apr 29 '14 at 06:58
  • [http://pastebin.com/KzkuwjtV](http://pastebin.com/KzkuwjtV). It has a lot of includes you will not need because I use it for testing other people's code. – jww Apr 29 '14 at 07:05
  • @j.atec - How did you make out? – jww Apr 29 '14 at 14:27
  • Here is me trying to use my code next to your working code. http://codepaste.net/i46u6w . I get an error "FileSink: error opening file for writing: " even when I have your picture in instead of "sample_files/1MB.png" – j.atec Apr 30 '14 at 03:58
  • Interesting... no error number. Do you have `rx` permission on the directory to list contents, and `rw` on the directory to access, create and delete files? Please post the relevant output of `ls -l `. – jww Apr 30 '14 at 04:01
  • Hmm I didn't have x permission. I changed it so now "-rwxrwxr-x 1 jack jack 1080639 Apr 7 00:01 1MB.png" but still doesn't work. – j.atec Apr 30 '14 at 04:38
  • If you are up for screen sharing to mentor me through google, the email on my profile is through google. – j.atec Apr 30 '14 at 04:44
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/51719/discussion-between-j-atec-and-jww) – j.atec Apr 30 '14 at 04:47
  • Be sure to do a `chmod -R 0770`. The `-R` applies the new permissions recursively. If its not permissions, ensure the drive is *not* mounted read only. Also, ensure there is room on the drive. Finally, see if you can solve it with `"./puppy-and-teddy-orig.jpg"`. Note the leading `./` to indicate present working directory. Otherwise, the folks on [Super User](http://www.superuser.com) might be able to help. I'm not a Linux hardware/Linux OS guy, so I probably can't help you any more. – jww Apr 30 '14 at 05:24
  • see http://stackoverflow.com/questions/23400054/what-is-the-difference-between-filesink-stringsink-filesource-stringsource-cr – j.atec Apr 30 '14 at 23:57