我是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,然后解密密文 .
//解密
ECB_Mode< AES >::Decryption Decryptor( key, sizeof(key) );
byte cbRecoveredText[AES::BLOCKSIZE];
Decryptor.ProcessData( cbRecoveredText, cbCipherText, sizeof(cbCipherText) );
上面的代码适用于小数据(16KB) . 但它不适用于大数据,因为“不是块大小的倍数” . 然后,我考虑使用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的文本加密()函数时,将加密的字符串“cipher”写入“ss1.txt”,它的1MB也是如此 . 但对于“可写”,它只是“密码”(约1KB)的一部分,而解密结果也是原始文本的一部分 . 好像'\ 0'在某处遇到了它终止了我的char数组?我现在想要四处走动 . 有没有办法使用Crypto与(任何)大字节(二进制)数组?
另外,我想避免使用FileSource(加密),因为它不允许我将加密值保存到变量 .