如何在Blowfish Crypto++上循环
How to loop over Blowfish Crypto++
我正在运行Crypto++,对加密算法进行速度测试。我正在计算加密和解密数据所需的时间(最终使用更多的文件大小和不同的算法)。我遇到了一个问题,无法对代码进行循环。在下面的代码中,我使用Blowfish,但当我进入加密部分时,它会给我错误:
HashVerificationFilter: message hash or MAC not valid
我能做些什么来解决这个问题?我需要把它放在函数中吗?如果是,我该怎么做?
/**
* g++ encryption_tests.cpp -o encryption_tests -lcryptopp -lpthread -L.
*/
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
#include <ctime>
#include "cryptoplusplus/osrng.h"
using CryptoPP::AutoSeededRandomPool;
#include "cryptoplusplus/cryptlib.h"
using CryptoPP::Exception;
#include "cryptoplusplus/hex.h"
using CryptoPP::HexEncoder;
using CryptoPP::HexDecoder;
#include "cryptoplusplus/modes.h"
#include "cryptoplusplus/aes.h"
#include "cryptoplusplus/filters.h"
using CryptoPP::StringSink;
using CryptoPP::StringSource;
using CryptoPP::AuthenticatedEncryptionFilter;
using CryptoPP::AuthenticatedDecryptionFilter;
using namespace std;
#include "cryptoplusplus/filters.h"
using CryptoPP::StringSink;
using CryptoPP::StringSource;
using CryptoPP::AuthenticatedEncryptionFilter;
using CryptoPP::AuthenticatedDecryptionFilter;
#include "cryptoplusplus/blowfish.h"
using CryptoPP::Blowfish;
#include "crypto++/eax.h"
using CryptoPP::EAX;
#include "cryptoplusplus/secblock.h"
using CryptoPP::SecByteBlock;
int main( int argc, char* argv[] ) {
// Declaring variables
const int NUMBER_OF_RUNS = 3;
const int NUMBER_OF_TXT_FILES = 9;
const int NUMBER_OF_JPG_FILES = 6;
const int NUMBER_OF_PNG_FILES = 6;
const int NUMBER_OF_AVI_FILES = 2;
string file_names_txt[NUMBER_OF_TXT_FILES] = { "10B.txt", "100B.txt", "1KB.txt", "10KB.txt", "100KB.txt", "1MB.txt", "5MB.txt", "10MB.txt", "20MB.txt" };
string file_names_jpg[NUMBER_OF_JPG_FILES] = { "1KB.jpg", "10KB.jpg", "100KB.jpg", "1MB.jpg", "3MB.jpg", "5MB.jpg" };
string file_names_png[NUMBER_OF_PNG_FILES] = { "100B.png", "500B.png","1KB.png", "10KB.png","1MB.png", "5MB.png" };
string file_names_avi[NUMBER_OF_AVI_FILES] = { "4MB.avi", "10MB.avi" };
int time_data [NUMBER_OF_RUNS];
string plaintext, cipher, encoded, recovered, sample_files_path, data_file, line_contents;
string initial_cpp_time_data = "";
clock_t time_start, time_stop;
double run_time, time_difference, time_average = 0;
// This loop will run the test NUMBER_OF_RUNS times
for ( int i = 0 ; i < NUMBER_OF_RUNS ; i++ ) {
time_start = clock();
// This class seeds itself using an operating system provided RNG
AutoSeededRandomPool prng;
// Generate a random key
SecByteBlock key(Blowfish::DEFAULT_KEYLENGTH);
prng.GenerateBlock(key, key.size());
// Generate a random initialization vector
byte iv[Blowfish::BLOCKSIZE];
prng.GenerateBlock(iv, sizeof(iv));
// Set key width
EAX< Blowfish >::Encryption e;
e.SetKeyWithIV(key, key.size(), iv);
// Grab the data from the file we want to run the test on
sample_files_path = "sample_files/" + file_names_txt[8];
ifstream initial_file_contents ( sample_files_path.c_str() );
if (initial_file_contents.is_open()) {
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;
}
// Encrypts the plaintext
try {
StringSource(plaintext, true, new AuthenticatedEncryptionFilter(e, new StringSink(cipher) ) );
} catch ( const CryptoPP::Exception& e ) {
cerr << e.what() << endl;
exit(1);
}
// Decrypts the test
try {
EAX< Blowfish >::Decryption d;
d.SetKeyWithIV(key, key.size(), iv);
StringSource s(cipher, true, new AuthenticatedDecryptionFilter( d, new StringSink(recovered) ) );
} catch ( const CryptoPP::Exception& e ) {
cerr << e.what() << endl;
exit(1);
}
// Stop the clock, calculate the time difference, turn to milliseconds
time_stop = clock();
time_difference = time_stop - time_start;
run_time = time_difference / ( CLOCKS_PER_SEC / 1000 );
time_data[i] = run_time;
cout << "time_data[" << i << "]: " << time_data[i] << " milliseconds" << endl;
}
//Grab the data from the old file
ifstream initial_cpp_time_data_file ( "cpp_time_data.txt" );
if (initial_cpp_time_data_file.is_open()) {
while ( getline( initial_cpp_time_data_file, line_contents ) ) {
initial_cpp_time_data = initial_cpp_time_data + line_contents;
initial_cpp_time_data.push_back('n');
}
initial_cpp_time_data_file.close();
} else {
initial_cpp_time_data = "";
}
// Created a new file
ofstream time_data_file;
time_data_file.open("cpp_time_data.txt");
// Insert old data first
time_data_file << initial_cpp_time_data << endl;
// Show the file the test ran on and insert the new data
time_data_file << sample_files_path << endl;
for ( int i = 0 ; i < NUMBER_OF_RUNS ; i++ ) {
time_data_file << "time_data[" << i << "]: " << time_data[i] << " milliseconds" << endl;
time_average = time_average + time_data[i];
}
time_average = time_average / NUMBER_OF_RUNS;
time_data_file << "The average time for this is " << time_average << " milliseconds" << endl;
cout << "The average time for this is " << time_average << " milliseconds" << endl;
time_data_file.close();
cout << "Done!n";
return 0;
}
在循环的每次迭代中,您必须调用:
cipher.clear()
recovered.clear()
否则,StringSink
只是继续添加到上一个值的末尾。您将在循环的第二次和后续迭代中失败(第一次应该可以)。
此外,没有Resynchronize
,因此不能调用e.Resynchronize(iv)
来重新启动密码。您必须在循环的每次迭代中调用e.SetKeyWithIV(key, key.size(), iv)
。
下面,我无法重复您的重用问题。加密对象被重用,而解密对象则为每次迭代创建新对象。运行程序的结果:
$ ./cryptopp-test.exe
plain text: String 1
recovered text: String 1
plain text: String 2
recovered text: String 2
plain text: String 3
recovered text: String 3
plain text: String 4
recovered text: String 4
plain text: String 5
recovered text: String 5
AutoSeededRandomPool prng;
SecByteBlock key(Blowfish::DEFAULT_KEYLENGTH);
prng.GenerateBlock( key, key.size() );
byte iv[ Blowfish::BLOCKSIZE ];
prng.GenerateBlock( iv, sizeof(iv) );
vector<string> vv;
vv.push_back("String 1");
vv.push_back("String 2");
vv.push_back("String 3");
vv.push_back("String 4");
vv.push_back("String 5");
string plain, cipher, recovered;
try {
EAX< Blowfish >::Encryption e1;
e1.SetKeyWithIV( key, key.size(), iv, sizeof(iv) );
for(unsigned i = 0; i < vv.size(); i++)
{
/*********************************
*********************************/
plain = vv[i];
cout << "plain text: " << plain << endl;
e1.SetKeyWithIV( key, key.size(), iv, sizeof(iv) );
cipher.clear();
StringSource ss1(plain, true,
new AuthenticatedEncryptionFilter( e1,
new StringSink( cipher )
) ); // StringSource
/*********************************
*********************************/
EAX< Blowfish >::Decryption d2;
d2.SetKeyWithIV( key, key.size(), iv, sizeof(iv) );
recovered.clear();
StringSource ss2(cipher, true,
new AuthenticatedDecryptionFilter( d2,
new StringSink( recovered ),
AuthenticatedDecryptionFilter::THROW_EXCEPTION
) ); // StringSource
cout << "recovered text: " << recovered << endl;
}
} catch (const Exception& ex) {
cerr << ex.what() << endl;
}
相关文章:
- 如何循环打印顶点结构
- 如何在C++中从两个单独的for循环中添加两个数组
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 正在尝试了解输入验证循环
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 循环后如何继续阅读
- Ardunio UNO解决了多个重叠的定时器循环
- Eigen如何在容器循环中干净地附加矩阵
- 在某些循环内使用vector.push_back时出现分段错误
- 我正在使用嵌套的while循环来解析具有多行的文本文件,但由于某种原因,它只通过第一行,我不知道为什么
- 为什么我的for循环不能正确获取argv
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- while循环中while循环的时间复杂度是多少
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- 为什么在这个代码结束循环中没有得到结束
- 在基于范围的for循环中使用结构化绑定声明
- 用于C++中带有数组和指针的循环
- 循环中的随机函数
- 是什么阻止DOMTimerCoordinator::NextID进入无休止的循环
- 如何在Blowfish Crypto++上循环