在 Crypto++ 中使用 RSA 加密对称 AES 密钥
Encrypt a symmetric AES key with RSA in Crypto++
我正在尝试在两个 parts.The 之间交换 AES 密钥 AES 密钥将使用接收方的 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:: ArraySource
还是 CryptoPP::StringSource
?
... after I don't know what to use : CryptoPP::ArraySource ? CryptoPP::StringSource ?
之后,使用PK_EncryptorFilter
作为RSA加密器;并使用 ArraySource
作为您尝试加密的密钥。 ArraySource
只是 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
中,您可以使用 TransferTo
和 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
您可能还对 Crypto++ wiki 上的 Pipelines 感兴趣。您在上面看到的东西是管道中使用的源、过滤器和接收器。
如果它应该保存加密的对称密钥,那么它太小了:
SecByteBlock cipher(AES::MAX_KEYLENGTH);
查看 Crypto++ wiki 上的 RSA Encryption Schemes。 cipher
需要是 encryptor.CiphertextLength(AES::MAX_KEYLENGTH);
,这大致是 RSA 模数的大小减去 OAEP 格式和填充的大约 50 个字节。
(comment) > Now I am trying to add the part to decrypt it using the private key... Is this correct ?
StringSource(readed_key, true,
new PK_DecryptorFilter(rng, decryptor, new
FileSource("sessionkey.enc")));
嗯,过滤器部分是正确的(PK_DecryptorFilter
部分)。在 Crypto++ 中,数据从源流向接收器。所以一般的模式如下图所示。它被称为 Pipeline.
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)));
(comment) > ... and then compare the original ...
您可以用 VerifyBufsEqual
在几乎恒定的时间内比较两个字节缓冲区。同样,请参阅 Crypto++ wiki。
我正在尝试在两个 parts.The 之间交换 AES 密钥 AES 密钥将使用接收方的 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:: ArraySource
还是 CryptoPP::StringSource
?
... after I don't know what to use : CryptoPP::ArraySource ? CryptoPP::StringSource ?
之后,使用PK_EncryptorFilter
作为RSA加密器;并使用 ArraySource
作为您尝试加密的密钥。 ArraySource
只是 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
中,您可以使用 TransferTo
和 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
您可能还对 Crypto++ wiki 上的 Pipelines 感兴趣。您在上面看到的东西是管道中使用的源、过滤器和接收器。
如果它应该保存加密的对称密钥,那么它太小了:
SecByteBlock cipher(AES::MAX_KEYLENGTH);
查看 Crypto++ wiki 上的 RSA Encryption Schemes。 cipher
需要是 encryptor.CiphertextLength(AES::MAX_KEYLENGTH);
,这大致是 RSA 模数的大小减去 OAEP 格式和填充的大约 50 个字节。
(comment) > Now I am trying to add the part to decrypt it using the private key... Is this correct ?
StringSource(readed_key, true, new PK_DecryptorFilter(rng, decryptor, new FileSource("sessionkey.enc")));
嗯,过滤器部分是正确的(PK_DecryptorFilter
部分)。在 Crypto++ 中,数据从源流向接收器。所以一般的模式如下图所示。它被称为 Pipeline.
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)));
(comment) > ... and then compare the original ...
您可以用 VerifyBufsEqual
在几乎恒定的时间内比较两个字节缓冲区。同样,请参阅 Crypto++ wiki。