Как прочитать изображение в строку для шифрования Crypto++

Мне нужно прочитать файл как двоичные данные, а затем зашифровать и расшифровать его. Я тестирую скорости различных алгоритмов в Crypto++. До сих пор я использовал getline для чтения текстовых файлов.

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;
}

Я видел другие статьи, такие как Чтение файла изображения в C/C++ и Чтение двоичного файла (jpg) в строку с помощью c++ , но я не знаю, как это сделать. Мне кажется, что http://www.cplusplus.com/reference/istream/istream/read/ может быть хорошим примером, но я все еще не уверен, как это реализовать. Может ли кто-нибудь показать мне, как читать файл, такой как файл .jpg, и сохранять его в виде строки, чтобы я мог его зашифровать?

Если бы у меня был файл с именем image.jpg, как бы я прочитал его в строковой переменной, такой как открытый текст?


person j.atec    schedule 29.04.2014    source источник
comment
Может ли кто-нибудь показать мне, как это сделать? - Как сделать что?   -  person jww    schedule 29.04.2014
comment
@jww Мне нужно прочитать разные типы файлов в строку, чтобы я мог ее зашифровать.   -  person j.atec    schedule 29.04.2014
comment
Но вы сейчас читаете файлы, не так ли? Если вы хотите сделать двоичный файл, используйте флаг ios::binary. Или используйте Crypto++ FileSink и FileSource. Они изначально настроены на двоичный код и не требуют дополнительных флагов, таких как C++ istreams и ostreams.   -  person jww    schedule 29.04.2014
comment
getline преобразует конец строки, поэтому то, что вы читаете, не обязательно совпадает с тем, что находится в файле на диске. Если вы собираетесь открыть поток, вы должны сделать это с помощью ios::binary и использовать istream::read< /a> чтобы избежать преобразований.   -  person jww    schedule 29.04.2014
comment
@jww Да, я хотел бы, чтобы кто-нибудь показал, как это сделать, потому что я все еще немного потерян и новичок в C ++.   -  person j.atec    schedule 29.04.2014
comment
Кстати, в исходниках библиотеки crypto++ есть бенчмарк.   -  person Maciej S    schedule 30.04.2014


Ответы (1)


Используйте FileSource и FileSink. Он позволяет избежать чтения данных в промежуточный объект, такой как string, но, вероятно, в некоторых случаях он немного более эффективен.

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;
}

Вот изображение:

введите здесь описание изображения

Вот зашифрованное изображение в шестнадцатеричном редакторе:

введите здесь описание изображения

При его запуске нет разницы между исходным и восстановленным изображениями:

$ ./cryptopp-test.exe
$ diff puppy-and-teddy-orig.jpg puppy-and-teddy-recovered.jpg 
$

Если вы действительно хотите прочитать его в строку, вот соответствующие изменения:

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
               ) );
person jww    schedule 29.04.2014
comment
Ни один из них не может работать. Возможно, потому что я не очень хорошо знаю C++. Даже когда я говорю использовать CryptoPP::FileSource, он все еще говорит, encoding_tests.cpp:168:7: error: ‘FileSource’ не был объявлен в этой области. У меня по мануалу он находится в filter.h... - person j.atec; 29.04.2014
comment
#include <cryptopp/files.h>. cryptopp.com/docs/ref/files_8h_source.html. - person jww; 29.04.2014
comment
В любом случае, вы могли бы опубликовать всю программу со всеми включениями? Если бы я мог запустить его, я бы смог понять, чего именно мне не хватает. Спасибо! - person j.atec; 29.04.2014
comment
http://pastebin.com/KzkuwjtV. В нем много включений, которые вам не понадобятся, потому что я использую его для тестирования чужого кода. - person jww; 29.04.2014
comment
@j.atec - Как ты разобрался? - person jww; 29.04.2014
comment
Вот я пытаюсь использовать свой код рядом с вашим рабочим кодом. codepaste.net/i46u6w . Я получаю сообщение об ошибке FileSink: ошибка при открытии файла для записи: даже когда у меня есть ваша картинка вместо sample_files/1MB.png - person j.atec; 30.04.2014
comment
Интересно... нет номера ошибки. Есть ли у вас разрешение rx на каталог для вывода списка содержимого и rw на доступ к каталогу, создание и удаление файлов? Пожалуйста, опубликуйте соответствующий вывод ls -l <dir>. - person jww; 30.04.2014
comment
Хм, у меня не было разрешения x. Я изменил его так, что теперь -rwxrwxr-x 1 jack jack 1080639 7 апреля 00:01 1MB.png, но все равно не работает. - person j.atec; 30.04.2014
comment
Если вы хотите поделиться экраном, чтобы наставлять меня через Google, электронная почта в моем профиле отправляется через Google. - person j.atec; 30.04.2014
comment
давайте продолжим это обсуждение в чате - person j.atec; 30.04.2014
comment
Обязательно сделайте chmod -R 0770. -R применяет новые разрешения рекурсивно. Если это не разрешения, убедитесь, что диск не смонтирован только для чтения. Также убедитесь, что на диске есть место. Наконец, посмотрите, сможете ли вы решить ее с помощью "./puppy-and-teddy-orig.jpg". Обратите внимание на ./ в начале, чтобы указать текущий рабочий каталог. В противном случае люди из Super User могут помочь. Я не разбираюсь в оборудовании Linux/ОС Linux, поэтому я, вероятно, больше не могу вам помочь. - person jww; 30.04.2014
comment
см. stackoverflow.com/questions/23400054/ - person j.atec; 01.05.2014