如何循环Blowfish Crypto ++ [英] How to loop over Blowfish Crypto++

查看:250
本文介绍了如何循环Blowfish Crypto ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在运行Crypto ++对加密算法进行速度测试。我试图时间加密需要多长时间,然后解密数据(最终有更多的文件大小和不同的算法)。我遇到了一个问题,我不能循环代码。在下面的代码中,我使用Blowfish,但当我到达加密部分,它给我的错误:

I am running Crypto++ doing speed tests on encryption algorithms. I am trying to time how long it takes to encrypt, then decrypt the data(eventually with more file sizes and different algorithms). I am running into a problem where I cannot loop over the code. In the following code, I am using Blowfish, but when I get to the encryption part, it gives me the error:

HashVerificationFilter: message hash or MAC not valid

我能做什么来解决这个问题?我需要把它放在一个函数中吗?如果是,我该怎么做?

What can I do to fix this? Do I need to put it in a function? If so, how would I do that?

/**
 * 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()

  • restored.clear()

  • cipher.clear()
  • recovered.clear()

StringSink '只是继续添加到上一个值的结尾。

Otherwise, the StringSink's just keep adding to the end of a previous value. You will fail on the 2nd and subsequent iterations of your loop (the 1st should be OK).

此外,没有重新同步,因此您不能调用 e.Resynchronize(iv)以重新启动密码。您必须在循环的每次迭代中调用 e.SetKeyWithIV(key,key.size(),iv)

Also, there is no Resynchronize, so you can't call e.Resynchronize(iv) to restart a cipher. You have to call e.SetKeyWithIV(key, key.size(), iv) at each iteration of your loop.

以下,我无法复制您的重复使用问题。加密对象被重用,而解密对象为每次迭代创建新的。运行程序的结果:

Below, I could not duplicate your reuse problem. The encryption object was reused, while the decryption object was created new for each iteration. The result of running the program:

$ ./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

$ b b





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

这篇关于如何循环Blowfish Crypto ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆