如何将EVP_PKEY发送给其他方?

时间:2017-10-31 23:27:29

标签: c++ encryption openssl aes rsa

目前我正在努力使用OpenSSL API for C ++。我正在使用EVP函数生成RSA密钥对,然后用于加密用于加密数据的AES密钥(混合加密)。

密钥生成:

EVP_PKEY* keypair = NULL;
EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
EVP_PKEY_keygen_init(ctx);
EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 4096);
EVP_PKEY_keygen(ctx, &keypair);
EVP_PKEY_CTX_free(ctx);

现在我有一个密钥对。通过EVP_SealInit / EVP_SealUpdate / EVP_SealFinal在我自己的计算机上加密消息时没有问题。对于解密过程也是如此。我只是将keypair作为SealInit / OpenInit函数的参数。

但是考虑一下我想生成一个密钥对,并将公钥或私钥作为char *通过套接字发送给另一个人:我该怎么做?

我在Internet上找到的一种方法是使用PEM_write_bio_PUBKEY或PEM_write_bio_PrivateKey将Keys转换为char *。尝试它似乎工作。但我仍然不是百分百肯定。所以,请查看我的代码并告诉我这些功能是否可行:

unsigned char* publicKey;
BIO* bio = BIO_new(BIO_s_mem());
PEM_write_bio_PUBKEY(bio, keypair);
RSAmakeString(&publicKey, bio);

unsigned char* privateKey;
BIO* bio = BIO_new(BIO_s_mem());
PEM_write_bio_PrivateKey(bio, keypair, NULL, NULL, 0, 0, NULL);
RSAmakeString(&privateKey, bio);

另一件事是如何将char *转换回EVP_PKEY *?有什么功能吗?因为如果我想在另一台计算机上使用SealInit和我的公钥,我必须将它从char *转换回EVP_PKEY *,所以我可以在函数中使用它。有什么建议吗?

1 个答案:

答案 0 :(得分:0)

  

但是考虑一下我想生成一个密钥对,并将公钥或私钥作为char *通过套接字发送给另一个人:我该怎么做?

您需要一些序列化和有线格式或演示文稿格式。您的公钥和加密邮件可能包含0个字符,这些字符显示为嵌入式NULL。所以你需要同时具有缓冲区和显式长度。

使用Google的ProtocolBuffersBinary JSON甚至ASN.1 / DER编码。我认为Google的ProtocolBuffers是面向邮件的,因此在完整邮件可用之前,他们不会返回邮件。

你也可以对Hex,Base32或Base64进行编码。但是你仍然需要传达一个长度,以便接收方知道他们得到了整个消息。在本地局域网上,您可能永远不会遇到问题。在互联网上,你偶尔可能会遇到失误,因为你偶尔会进行简短的阅读。

您对PEM_write_bio_PUBKEY的想法实际上是对密钥进行Base64编码,因此它遇到与Hex,Base32或Base64编码相同的潜在问题。

  

如何将char *转换回EVP_PKEY

好吧,根据您上面的更改,您可能不会使用char*。完善设计后,您应该提出一个新问题。

但目前,如果您使用PEM_write_bio_PUBKEYPEM_write_bio_PrivateKey保存了密钥,那么您将分别使用PEM_read_bio_PUBKEYPEM_read_bio_PrivateKey。另请参阅OpenSSL的PEM man page

与C ++相关,这是使用OpenSSL时的一些技巧。如果您使用的是C ++ 11,那么unique_ptr可以很容易地使用一些OpenSSL对象。