簡體   English   中英

使用Crypto ++中的RSA加密對稱AES密鑰

[英]Encrypt a symmetric AES key with RSA in Crypto++

我正在嘗試在兩個部分之間交換AES密鑰publicKey密鑰將使用接收者的RSA publicKey加密,然后寫入文件。

我正在使用Crypto ++庫,這是我的程序的開始:

//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());

(你會認識到Crypto ++ wiki的例子)

然后我開始加密例程:

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

CryptoPP::RSAES_OAEP_SHA_Encryptor e(publicKey);

我不知道使用哪一個: CryptoPP:: ArraySourceCryptoPP::StringSource

...之后我不知道該用什么:CryptoPP :: ArraySource? CryptoPP :: StringSource?

在此之后,為RSA加密器使用PK_EncryptorFilter ; 並使用ArraySource作為您嘗試加密的密鑰。 一個ArraySource僅僅是一個一個typedef StringSource ,所以你真的只是使用StringSource

代碼看起來如下所示。 我沒有運行這些示例,所以請修改錯別字。

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")));

您可以使用類似的內容將其寫入std::string

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

您也可以使用ByteQueue Redirector打破了所有權鏈。 另請參閱Crypto ++ wiki上的Redirector

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

ByteQueue很酷,因為它們包裝了SecByteBlock 進入ByteQueue您可以使用TransferToCopyTo移動字節:

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

您可能還對Crypto ++ wiki上的Pipelines感興趣。 您在上面看到的東西是管道中使用的源,過濾器和接收器。


如果這應該保存加密的對稱密鑰,那么它太小了:

SecByteBlock cipher(AES::MAX_KEYLENGTH);

看一下Crypto ++ wiki上的RSA加密方案 cipher需要是encryptor.CiphertextLength(AES::MAX_KEYLENGTH); ,這大約是RSA模數的大小減去OAEP格式和填充的大約50個字節。


(評論)>現在我正在嘗試添加部分以使用私鑰解密它...這是正確的嗎?

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

好吧,過濾器部分是正確的( PK_DecryptorFilter部分)。 在Crypto ++中,數據從源流向接收器。 所以一般模式如下所示。 它被稱為管道

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

通常你想要像下面這樣的東西。 Redirector打破了所有權鏈。 另請參閱Crypto ++ wiki上的Redirector

// 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)));

(評論)> ...然后比較原始...

您可以使用VerifyBufsEqual在幾乎恆定的時間內比較兩個字節的緩沖區。 再次,請參閱Crypto ++ wiki。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM