c++ - 如何发送 EVP_PKEY 给对方?

标签 c++ encryption openssl aes rsa

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

key 生成:

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

现在我有了一个 key 对。通过 EVP_SealInit/EVP_SealUpdate/EVP_SealFinal 在我自己的机器上加密消息时没有问题。解密过程相同。我只是将 key 对作为 SealInit/OpenInit 函数的参数。

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

我在互联网上找到的一种方法是使用 PEM_write_bio_PUBKEY 或 PEM_write_bio_PrivateKey 将 key 转换为 char*。尝试时似乎有效。但我仍然不是 100% 确定。所以请查看我的代码并告诉我这些功能是否可行:

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*,这样我才能在函数中使用它。有什么建议吗?

最佳答案

But consider that I want to generate a keypair and send the public or private key as a char* over a socket to another person: how do I do that?

您需要一些用于序列化和有线格式或演示格式的东西。您的公钥和加密消息可能包含 0 个字符,这些字符显示为嵌入的 NULL。因此,您需要同时拥有缓冲区和显式长度。

使用谷歌的 ProtocolBuffers , Binary JSON ,甚至 ASN.1/DER 编码。我认为 Google 的 ProtocolBuffers 是面向消息的,因此在完整消息可用之前它们不会返回消息。

您还可以对其进行十六进制、Base32 或 Base64 编码。但是您仍然需要传达一定的长度,以便接收方知道他们收到了完整的消息。在本地 LAN 上,您可能永远不会遇到问题。在 Internet 上,您可能偶尔会遇到失败,因为您有时会执行简短的读取操作。

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


how do I convert the char* back to EVP_PKEY

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

但目前,假设您使用 PEM_write_bio_PUBKEYPEM_write_bio_PrivateKey 保存了 key ,那么您将使用 PEM_read_bio_PUBKEYPEM_read_bio_PrivateKey ,分别。另请参阅 OpenSSL 的 PEM man page .


与 C++ 相关,以下是使用 OpenSSL 时的一些技巧。如果您使用的是 C++11,那么 unique_ptr 确实可以轻松处理某些 OpenSSL 对象。

关于c++ - 如何发送 EVP_PKEY 给对方?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47045979/

相关文章:

encryption - 同态加密中的截断

c# - 使用 BouncyCaSTLe 在 C# 中读取 DER 私钥

c++ - cmake在Mac OS X上找不到openssl库(尽管手动添加)

node.js - 如何将 base64 字符串作为 Openssl 的输入证书传递?

c++ - 在自定义类中重载运算符 <<(单例)

c++ - CInternetSession 安全吗?它被加密了吗?

c++ - Qt4 + CGAL - "BOOST_JOIN"处的解析错误

windows - PHP7 Curl 和 OpenSSL 扩展不适用于 Windows 上的 Apache 2 处理程序

被跳过的 C++ 函数

c++ - 当两个成员都在同一个类中时出现错误 "a nonstatic member reference must be relative to a specific object"