Encrypting AES Symmetric Key with RSA in Crypto ++

I am trying to exchange an AES key between two parts. The AES key will be encrypted with the RSA receiver publicKey

and then written to a file.

I am using Crypto ++ library and here is the start of my program:

//generate key pair
CryptoPP::AutoSeededRandomPool rng;
CryptoPP::RSAES_OAEP_SHA_Decryptor priv(rng, 4096);

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

//generate aes key (256bits)
SecByteBlock key(AES::MAX_KEYLENGTH);
rnd.GenerateBlock(key, key.size());

      

(You will learn an example of the Crypto ++ wiki)

Then I run the encryption routine:

CryptoPP::SecByteBlock cipher(CryptoPP::AES::MAX_KEYLENGTH), decrypted_data(CryptoPP::AES::MAX_KEYLENGTH);

CryptoPP::RSAES_OAEP_SHA_Encryptor e(publicKey);

      

I don't know which one to use: CryptoPP:: ArraySource

or CryptoPP::StringSource

?

+3


source to share


1 answer


... after I don't know what to use: CryptoPP :: ArraySource? CryptoPP :: StringSource?

Then use PK_EncryptorFilter

RSA for encryption; and use ArraySource

for the key you are trying to encrypt. ArraySource

is just a typedef for StringSource

, so you actually use StringSource

.

The code will look something like this: I haven't run the examples, so please correct the typos.

SecByteBlock key(AES::MAX_KEYLENGTH);
rng.GenerateBlock(key, key.size());
...

RSAES_OAEP_SHA_Encryptor encryptor(publicKey);
...

ArraySource as(key, key.size(), true, /* pump all data */
    new PK_EncryptorFilter(rng, encryptor,
        new FileSink("session-key.enc")));

      

You can write it in std::string

with something like:

std::string session_key;
ArraySource as(key, key.size(), true, /* pump all data */
    new PK_EncryptorFilter(rng, encryptor,
        new StringSink(session_key)));

      

You can also get fancy and use ByteQueue

. Redirector

destroys the chain of ownership. Also see the Redirector

Crypto ++ wiki.

ByteQueue queue;
ArraySource as(key, key.size(), true, /* pump all data */
    new PK_EncryptorFilter(rng, encryptor,
        new Redirector(queue)));

      

ByteQueue

are great because they complete SecByteBlock

. In ByteQueue

you can move bytes with TransferTo

and CopyTo

:

ByteQueue queue;
ArraySource as(key, key.size(), true, /* pump all data */
    new PK_EncryptorFilter(rng, encryptor,
        new Redirector(queue)));

// Copy bytes to a file
FileSink sink1("session-key.enc");
queue.CopyTo(sink1);

// Copy bytes to std::out
HexEncoder encoder(new FileSink(std::cout));
queue.CopyTo(encoder);

// Transfer bytes to a SecByteBlock.
SecByteBlock block(queue.MaxRetrievable());
ArraySink sink2(block, block.size());
queue.TransferTo(sink2);
// No bytes remain in the queue

      

You may also be interested in the Pipelines on the Crypto ++ wiki. The material you see above is the sources, filters and sinks used in the conveyor.




If it is assumed to contain an encrypted symmetric key, then it is too small:

SecByteBlock cipher(AES::MAX_KEYLENGTH);

      

Take a look at RSA Encryption Schemes on the Crypto ++ wiki. cipher

should be encryptor.CiphertextLength(AES::MAX_KEYLENGTH);

that roughly equal to the size of the RSA unit minus about 50 bytes for OAEP formatting and padding.




(comment)> Now I am trying to add a part so I can decrypt it with the private key ... Is that correct?

StringSource(readed_key, true,
    new PK_DecryptorFilter(rng, decryptor, new 
        FileSource("sessionkey.enc")));

      

Well, the filter part is correct (part PK_DecryptorFilter

). In Crypto ++, data is transferred from source to destination. Thus, the general scheme is shown below. It is called the Pipeline .

Source(..., new Filter(..., new Filter(..., new Sink(...))));

      

Usually you want something like the following. Redirector

destroys the chain of ownership. Also see the Redirector

Crypto ++ wiki.

// decrypted, in-memory
SecByteBlock session_key(AES::MAX_KEYLENGTH);
ArraySink sink(session_key, session_key.size());

FileSource fs("sessionkey.enc", true,
    new PK_DecryptorFilter(rng, decryptor, 
        new Redirector(sink)));

      




(comment)> ... and then compare the original ...

You can compare two byte buffers at almost constant time with VerifyBufsEqual

. Again, see the Crypto ++ wiki.

+2


source







All Articles