我需要将文件读取为二进制数据,然后才能对其进行加密和解密。我正在测试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;
}
我见过其他文章,例如Reading an image file in C/C++和Read a binary file (jpg) to a string using c++,但我不确定该怎么做。我觉得http://www.cplusplus.com/reference/istream/istream/read/可能是一个很好的例子,但我仍然不确定如何实现它。有人可以告诉我如何读取.jpg文件等文件,并将其存储为字符串,以便加密吗?
如果我有一个名为image.jpg的文件,我怎么读它才能像明文一样在字符串变量中?
答案 0 :(得分: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
) );