使用带有Crypto ++的{std :: string}加密大字符*

时间:2016-11-14 10:26:51

标签: c++ arrays crypto++ large-data

我是Crypto ++的新手。我想使用Crypto ++库来加密/解密C ++中的大字节数组。数据可以是任何数据,因此可以使用其二进制格式。 首先,我尝试使用"字节数组" (char *或char [])。

byte PlainText[] = {
  'H','e','l','l','o',' ',
  'W','o','r','l','d',
  0x0,0x0,0x0,0x0,0x0
};

byte key[ AES::DEFAULT_KEYLENGTH ];
::memset( key, 0x01, AES::DEFAULT_KEYLENGTH );

// Encrypt
ECB_Mode< AES >::Encryption Encryptor( key, sizeof(key) );

byte cbCipherText[AES::BLOCKSIZE];

Encryptor.ProcessData( cbCipherText, PlainText, sizeof(PlainText) );

我们使用ProcessData()来加密纯文本,因为它允许我们在一行代码中接收结果。接下来,我们输入DMZ,然后解密密文。

// Decrypt

ECB_Mode< AES >::Decryption Decryptor( key, sizeof(key) );

byte cbRecoveredText[AES::BLOCKSIZE];

Decryptor.ProcessData( cbRecoveredText, cbCipherText, sizeof(cbCipherText) );

上面的代码适用于小数据(16KB)。但它并不适用于大数据,因为&#34;不是块大小的倍数&#34;。然后,我考虑使用StreamTransformationFilter,它可以自动为我做填充工作。所以我尝试使用encryptString()和decryptString()加密和解密std :: string,如下所示:

string  encryptString(string plain, byte key[], int sizeKey, byte iv[], int sizeIV){
    string cipher;
    try{
        CBC_Mode< AES >::Encryption e;
        e.SetKeyWithIV(key, sizeKey, iv, sizeIV);

        // The StreamTransformationFilter removes
        //  padding as required.
        StringSource s(plain, true,
            new StreamTransformationFilter(e,
            new StringSink(cipher)
            ) // StreamTransformationFilter
            ); // StringSource

#if 0
        StreamTransformationFilter filter(e);
        filter.Put((const byte*)plain.data(), plain.size());
        filter.MessageEnd();

        const size_t ret = filter.MaxRetrievable();
        cipher.resize(ret);
        filter.Get((byte*)cipher.data(), cipher.size());
#endif
        return cipher;
    }
    catch (const CryptoPP::Exception& e)
    {
        cerr << e.what() << endl;
        return NULL;
    }
}

string  decryptString(string cipher, byte key[], int sizeKey, byte iv[], int sizeIV){
    string reco;
    try{
        CBC_Mode< AES >::Decryption d;
        d.SetKeyWithIV(key, sizeKey, iv, sizeIV);

        StringSource s(cipher, true,
            new StreamTransformationFilter(d,
            new StringSink(reco)
            ) // StreamTransformationFilter
            ); // StringSource

#if 0
        StreamTransformationFilter filter(e);
        filter.Put((const byte*)plain.data(), plain.size());
        filter.MessageEnd();

        const size_t ret = filter.MaxRetrievable();
        cipher.resize(ret);
        filter.Get((byte*)cipher.data(), cipher.size());
#endif
        return reco;
    }
    catch (const CryptoPP::Exception& e)
    {
        cerr << e.what() << endl;
        return reco;
    }
}

它们也适用于大型文本文件。但是,等等,我的目标是加密/解密任何字节数组。有时它们不是字符串。 所以我想把上面两个函数包装起来用char *。

//wrap encryptString()
char* encrypt(char * plainText, byte key[], int sizeKey, byte iv[], int sizeIV){
    string cipher = encryptString(plainText, key, sizeKey, iv, sizeIV);
    FileUtil::writeFile("ss1.txt", cipher, cipher.length());
    long len = cipher.size() + 1;
     char * writable = new  char[len];
    std::copy(cipher.begin(), cipher.end(), writable);
    writable[len] = '\0'; 

    // don't forget to free the string after finished using it
    //delete[] writable;
    return writable;
}

//wrap decryptString()
char* decrypt(char * cipher,  byte key[], int sizeKey, byte iv[], int sizeIV){
    long len = strlen(cipher);
    string recovered = decryptString(cipher, key, sizeKey, iv, sizeIV);
    char * writable = new char[recovered.size() + 1];
    std::copy(recovered.begin(), recovered.end(), writable);
    writable[recovered.size()] = '\0'; // don't forget the terminating 0

    // don't forget to free the string after finished using it
    //delete[] writable;
    return writable;
}

结果是: 当我读取1MB的文本加密()函数时,写下加密的字符串&#34; cipher&#34;到&#34; ss1.txt&#34;,它也是1MB。但对于#34;可写&#34;,它只是&#34; cipher&#34;的一部分。 (约1KB),解密结果也是原文的一部分。好像&#39; \ 0&#39;在某处遇到了它终止了我的char数组? 我现在想要四处走动。有没有办法将Crypto ++与(任何)大字节(二进制)数组一起使用?

此外,我想避免使用FileSource(Crypto ++),因为它不允许我将加密值保存到变量。

0 个答案:

没有答案