简体   繁体   中英

How to encrypt a byte array with Crypto++

How can I encrypt a byte array with Crypto++'s RSA implementation? I already found an example for strings. But I can't find a good example how to do the same for a byte array.

This is my first attempt:

//dataSize:     Size of data that is going to be send
//dataToSend    Bytes to send to the user
//seedPool      is an AutoSeededRandomPool

CryptoPP::RSAES_OAEP_SHA_Encryptor encryptor(publicKey);

int size = 64000; 
byte * cipher = new byte(size);

CryptoPP::ArraySink* test = new CryptoPP::ArraySink(cipher, size);
CryptoPP::ArraySource as((byte*)dataToSend, dataSize, true, new CryptoPP::PK_EncryptorFilter(seedPool, encryptor, test));

int newDataSize = test->TotalPutLength();
unsigned int bytesSend = ::send(socketLink, (char *)(cipher), (int)newDataSize, 0);

delete[] cipher;

This doesn't work. TotalPutLength will always return 0 but there is data put in cipher.

What is a safe way to implement this? I don't want to be vulnerable for buffer overflows or any other attack.

byte * cipher = new byte(size);

I believe this should be:

byte * cipher = new byte[size];

Otherwise, I think you get one byte initialized to 6400 (which is truncated to 0x00).


CryptoPP::ArraySink * test = new CryptoPP::ArraySink(cipher, size);

This is kind of different. You can stay out of the memory manager if you'd like:

 CryptoPP::ArraySink test(cipher, size);

int newDataSize = test->TotalPutLength();

I've never used TotalPutLength , and I did not see it documented on a BufferedTransformation or Sink . So I don't really have any advice on what its returning.

TotalPutLength is OK to use. An ArraySink could return the wrong value if the sink was full. It would happen if the array was fixed and too small for all the data. We cleared that issue at Crypto++ 5.6.3 or 5.6.4.

If you want to count the number of bytes processed (even if the sink cannot store they bytes), then you can also use a MeterFilter :

byte data[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };

string encoded;
MeterFilter meter( new StringSink( encoded ) );

ArraySource( data, sizeof( data ), true,
    new HexEncoder(
        new Redirector( meter ),
        true /*UCase*/, 2 /*Group*/,
        " " /*Separator*/
    )
);

cout << "processed " << meter.GetTotalBytes() << " bytes" << endl;
cout << encoded << endl;

Output:

Processed 23 bytes
00 01 02 03 04 05 06 07

How can you encrypt a byte array with Cryptopp RSA implementation

Now we're talking ;) Try this from the Crypto++ wiki on RSA Encryption .

////////////////////////////////////////////////
// Generate keys
AutoSeededRandomPool rng;

InvertibleRSAFunction params;
params.GenerateRandomWithKeySize( rng, 1536 );

RSA::PrivateKey privateKey( params );
RSA::PublicKey publicKey( params );

string plain="RSA Encryption", cipher, recovered;

////////////////////////////////////////////////
// Encryption
RSAES_OAEP_SHA_Encryptor e( publicKey );

StringSource ss1( plain, true,
    new PK_EncryptorFilter( rng, e,
        new StringSink( cipher )
    ) // PK_EncryptorFilter
 ); // StringSource

////////////////////////////////////////////////
// Decryption
RSAES_OAEP_SHA_Decryptor d( privateKey );

StringSource ss2( cipher, true,
    new PK_DecryptorFilter( rng, d,
        new StringSink( recovered )
    ) // PK_DecryptorFilter
 ); // StringSource

assert( plain == recovered );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM