问题描述
我正在尝试使用AES加密字节数组。我已经可以加密字符串和文件了,但是字节数组似乎对我不起作用。我传入一个要加密的字节数组,为了便于测试,我只是传入了crypto ++(bArrayToEncrypt)生成的AES密钥。加密似乎可以正常工作,但是解密确实可以工作。我还发现,加密中包含大量重复字符,这很奇怪。我在这里做错了什么?
I am trying to encrypt a byte array using AES. I have been able to encrypt strings and files no problem, however byte arrays seem to not be working for me. I pass in a byte array to be encrypted, for ease of testing I just pass in a generated AES key by crypto++ (bArrayToEncrypt). The encryption appears to be working but then the decryption does work at all. I also found it strange that the encryption has a large amount of duplicate characters. What I am doing wrong here??
我看到了类似的问题,但是它与RSA
有关,并且提供的示例对我已经运行的字符串进行了加密。
I saw a similar question Here, but it was pertaining to RSA as well as the example provided encrypts strings which I already have up a running.
size_t ksize = CryptoPP::AES::MAX_KEYLENGTH;
size_t vsize = CryptoPP::AES::BLOCKSIZE;
byte key[ksize];
byte testArray[ksize];
byte encryptedksize];
byte decrypted[ksize];
byte iv[vsize];
//generate key & iv, then generate a random byte array to encrypt/decrypt
CryptoPP::AutoSeededRandomPool prng;
prng.GenerateBlock(key, ksize);
prng.GenerateBlock(iv, vsize);
prng.GenerateBlock(testArray, ksize);
encrypt_barray(key, ksize, iv, vsize, testArray, ksize, encrypted);
//printed results here
decrypt_barray(key, ksize, iv, vsize, encrypted, ksize, decrypted);
//printed results here
Encrypt_barray
Encrypt_barray
void encrypt_barray(byte* key,
size_t kSize,
byte* iv,
size_t ivSize,
byte* bArrayToEncrypt,
size_t bArraySize,
byte* encrypted) {
CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption e;
e.SetKeyWithIV(key, kSize, iv, ivSize);
CryptoPP::ArraySource(key, true,
new CryptoPP::StreamTransformationFilter(e, new CryptoPP::ArraySink(encrypted, bArraySize)));
}
Decrypt_barray
Decrypt_barray
void decrypt_barray(byte* key,
size_t kSize,
byte* iv,
size_t ivSize,
byte* bArrayToDecrypt,
size_t bArraySize,
byte* decrypted) {
CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption d;
d.SetKeyWithIV(keyFromHash, kfhSize, iv1, iv1Size);
CryptoPP::ArraySource(keyToDecrypt, true,
new CryptoPP::StreamTransformationFilter(d, new CryptoPP::ArraySink(decrypted, bArraySize)));
}
输出:
Output:
Encrypted: ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠E1A2AFC5D820ADF7
7DB656DEF3245570╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╨Ñ♫
Decrypted: ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠E
1A2AFC5D820ADF77DB656DEF3245570╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╨Ñ♫
Press any key to continue . . .
推荐答案
以下是使用<$ c $的方法c> ArraySource 和 ArraySink
。 重定向器
确保 ArraySink
仍然存在,因此您可以调用 TotalPutLength
Here's the way to do things using ArraySource
and ArraySink
. The Redirector
ensures the ArraySink
survives so you can call TotalPutLength
.
#include <iostream>
#include <string>
using namespace std;
#include "cryptlib.h"
#include "filters.h"
#include "files.h"
#include "modes.h"
#include "hex.h"
#include "aes.h"
using namespace CryptoPP;
int main(int argc, char* argv[])
{
byte key[AES::MAX_KEYLENGTH];
byte iv[AES::BLOCKSIZE];
vector<byte> plain, cipher, recover;
HexEncoder encoder(new FileSink(cout));
memset(key, 0x00, sizeof(key));
memset(iv, 0x00, sizeof(iv));
string str("Attack at dawn!");
std::copy(str.begin(), str.end(), std::back_inserter(plain));
cout << "Plain text: ";
encoder.Put(plain.data(), plain.size());
encoder.MessageEnd();
cout << endl;
/////////////////////////////////////////////////////////////
CBC_Mode<AES>::Encryption enc;
enc.SetKeyWithIV(key, sizeof(key), iv, sizeof(iv));
// Make room for padding
cipher.resize(plain.size()+AES::BLOCKSIZE);
ArraySink cs(&cipher[0], cipher.size());
ArraySource(plain.data(), plain.size(), true,
new StreamTransformationFilter(enc, new Redirector(cs)));
// Set cipher text length now that its known
cipher.resize(cs.TotalPutLength());
cout << "Cipher text: ";
encoder.Put(cipher.data(), cipher.size());
encoder.MessageEnd();
cout << endl;
/////////////////////////////////////////////////////////////
CBC_Mode<AES>::Decryption dec;
dec.SetKeyWithIV(key, sizeof(key), iv, sizeof(iv));
// Recovered text will be less than cipher text
recover.resize(cipher.size());
ArraySink rs(&recover[0], recover.size());
ArraySource(cipher.data(), cipher.size(), true,
new StreamTransformationFilter(dec, new Redirector(rs)));
// Set recovered text length now that its known
recover.resize(rs.TotalPutLength());
cout << "Recovered text: ";
encoder.Put(recover.data(), recover.size());
encoder.MessageEnd();
cout << endl;
return 0;
}
运行程序会导致:
$ ./test.exe
Plain text: 41747461636B206174206461776E21
Cipher text: 85928E5511BFE9E6EE235BCACC4894D4
Recovered text: 41747461636B206174206461776E21
以下是使用 ByteQueue $ c $的示例c>。
重定向器
有助于将管道链接在一起,因为 ByteQueue
是 BufferedTransformation
。
Here's the example using ByteQueue
. The Redirector
helps chain the pipeline together because a ByteQueue
is a BufferedTransformation
.
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
#include "cryptlib.h"
#include "filters.h"
#include "files.h"
#include "modes.h"
#include "queue.h"
#include "hex.h"
#include "aes.h"
using namespace CryptoPP;
int main(int argc, char* argv[])
{
byte key[AES::MAX_KEYLENGTH];
byte iv[AES::BLOCKSIZE];
HexEncoder encoder(new FileSink(cout));
memset(key, 0x00, sizeof(key));
memset(iv, 0x00, sizeof(iv));
ByteQueue plain, cipher, recover;
string str("Attack at dawn!");
plain.Put(reinterpret_cast<const byte*>(str.data()), str.size());
cout << "Plain text: ";
plain.CopyTo(encoder);
encoder.MessageEnd();
cout << endl;
/////////////////////////////////////////////////////////////
CBC_Mode<AES>::Encryption enc;
enc.SetKeyWithIV(key, sizeof(key), iv, sizeof(iv));
StreamTransformationFilter f1(enc, new Redirector(cipher));
plain.CopyTo(f1);
f1.MessageEnd();
cout << "Cipher text: ";
cipher.CopyTo(encoder);
encoder.MessageEnd();
cout << endl;
/////////////////////////////////////////////////////////////
CBC_Mode<AES>::Decryption dec;
dec.SetKeyWithIV(key, sizeof(key), iv, sizeof(iv));
StreamTransformationFilter f2(dec, new Redirector(recover));
cipher.CopyTo(f2);
f2.MessageEnd();
cout << "Recovered text: ";
recover.CopyTo(encoder);
encoder.MessageEnd();
cout << endl;
return 0;
}
它还会导致:
skylake:cryptopp$ ./test.exe
Plain text: 41747461636B206174206461776E21
Cipher text: 85928E5511BFE9E6EE235BCACC4894D4
Recovered text: 41747461636B206174206461776E21
这篇关于加密/解密字节数组Crypto ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!