简体   繁体   English

如何发送 EVP_PKEY 给对方?

[英]How to send EVP_PKEY to other party?

I am struggling with the OpenSSL API for C++ at the moment.目前我正在为 C++ 的 OpenSSL API 苦苦挣扎。 I'm using the EVP functions to generate a RSA keypair which then is used to encrypt the AES key that was used for encrypting the data (hybrid encryption).我正在使用 EVP 函数生成一个 RSA 密钥对,然后用于加密用于加密数据(混合加密)的 AES 密钥。

Key generation:密钥生成:

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

Now I have a keypair.现在我有一个密钥对。 When Encrypting a message on my own machine via EVP_SealInit / EVP_SealUpdate / EVP_SealFinal there is no problem.通过 EVP_SealInit / EVP_SealUpdate / EVP_SealFinal 在我自己的机器上加密消息时没有问题。 Same for the decrypting process.解密过程相同。 I simply give keypair as an argument to the SealInit / OpenInit function.我只是将密钥对作为 SealInit / OpenInit 函数的参数。

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?但是考虑到我想生成一个密钥对并将公钥或私钥作为 char* 通过套接字发送给另一个人:我该怎么做?

One way I found in the Internet is using PEM_write_bio_PUBKEY or PEM_write_bio_PrivateKey to convert the Keys to char*.我在 Internet 上找到的一种方法是使用 PEM_write_bio_PUBKEY 或 PEM_write_bio_PrivateKey 将密钥转换为 char*。 When trying it seemed to work.当尝试它似乎工作。 But I'm still not 100% sure.但我仍然不是 100% 确定。 So Please look at my code and tell me if those functions are the way to go:所以请查看我的代码并告诉我这些功能是否可行:

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

The other thing is how do I convert the char* back to EVP_PKEY*?另一件事是如何将 char* 转换回 EVP_PKEY*? Are there any functions?有什么功能吗? Because if I want to use SealInit with my public Key on another computer I have to convert it back from a char* to an EVP_PKEY*, so I can use it in the function.因为如果我想在另一台计算机上将 SealInit 与我的公钥一起使用,我必须将它从 char* 转换回 EVP_PKEY*,所以我可以在函数中使用它。 Any suggestions?有什么建议?

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?但是考虑到我想生成一个密钥对并将公钥或私钥作为 char* 通过套接字发送给另一个人:我该怎么做?

You need something for serialization and wire formats or a presentation format.您需要一些用于序列化和有线格式或演示格式的东西。 Your public key and encrypted messages will likely have 0 characters, which appear as embedded NULL .您的公钥和加密消息可能有0字符,它们显示为嵌入的NULL So you need to have both a buffer and explicit length .因此,您需要同时拥有缓冲区和显式长度。

Use Google's ProtocolBuffers , Binary JSON , or even ASN.1/DER encoding.使用 Google 的ProtocolBuffersBinary JSON ,甚至 ASN.1/DER 编码。 I think Google's ProtocolBuffers are message oriented, so they won't return a message until the complete message is available.我认为 Google 的ProtocolBuffers是面向消息的,因此在完整消息可用之前它们不会返回消息。

You could also Hex, Base32 or Base64 encode it.您也可以对它进行十六进制、Base32 或 Base64 编码。 But you still need to communicate a length so the receiving party knows they got the whole message.但是您仍然需要传达一个长度,以便接收方知道他们收到了整个消息。 On a local LAN you will probably never experience a problem.在本地 LAN 上,您可能永远不会遇到问题。 Over the Internet you will probably get occasional failures as your perform short reads on occasion.在 Internet 上,您可能会偶尔遇到失败,因为您有时会执行短读操作。

Your thoughts on PEM_write_bio_PUBKEY are effectively Base64 encoding the key, so it suffers the same potential problem as Hex, Base32 or Base64 encoding.您对PEM_write_bio_PUBKEY想法PEM_write_bio_PUBKEY是对PEM_write_bio_PUBKEY进行 Base64 编码,因此它遇到与 Hex、Base32 或 Base64 编码相同的潜在问题。


how do I convert the char* back to EVP_PKEY我如何将 char* 转换回 EVP_PKEY

Well, you probably won't be using a char* based on your changes above.好吧,根据上述更改,您可能不会使用char* Once you refine the design, you should probably ask a new question.优化设计后,您可能应该提出一个新问题。

But at the moment, and given you saved the key with PEM_write_bio_PUBKEY and PEM_write_bio_PrivateKey , then you would use PEM_read_bio_PUBKEY or PEM_read_bio_PrivateKey , respectively.但是目前,如果您使用PEM_write_bio_PUBKEYPEM_write_bio_PrivateKey保存了密钥,那么您将分别使用PEM_read_bio_PUBKEYPEM_read_bio_PrivateKey Also see OpenSSL's PEM man page .另请参阅 OpenSSL 的PEM手册页


Related to C++, here are some tricks when working with OpenSSL.与 C++ 相关,这里有一些使用 OpenSSL 时的技巧。 If you are using C++11, then unique_ptr really makes it easy to work with some OpenSSL objects.如果您使用的是 C++11,那么unique_ptr确实可以轻松处理某些 OpenSSL 对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将 CNG 密钥转换为 OpenSSL EVP_PKEY(反之亦然)? - How to convert CNG key to OpenSSL EVP_PKEY (and vice versa)? 如何以可读的方式读写“EVP_PKEY”中包含的公钥和私钥? - How to read and write the public and private key contained in "EVP_PKEY" in a readable way? shared_ptr <EVP_PKEY> 使用EVP_PKEY_free作为自定义删除程序会导致堆损坏 - shared_ptr<EVP_PKEY> with EVP_PKEY_free as custom deleter causes heap corruption 使用OpenSSL 1.1生成EC密钥时仅使用1个EVP_PKEY - Using only 1 EVP_PKEY while generating EC keys using OpenSSL 1.1 错误:无法将参数&#39;1&#39;的&#39;std :: string&#39;转换为&#39;X509 *&#39;到&#39;EVP_PKEY * X509_get_pubkey(X509 *)&#39; - error: cannot convert ‘std::string’ to ‘X509*’ for argument ‘1’ to ‘EVP_PKEY* X509_get_pubkey(X509*)’ 为什么EVP_PKEY_keygen()失败? - Why does EVP_PKEY_keygen() fail? 使用EVP_PKEY_assign_RSA()或EVP_PKEY_set1_RSA()后,RSA_size()和EVP_PKEY_size()出现段错误 - segmen fault for RSA_size() and EVP_PKEY_size() after use EVP_PKEY_assign_RSA() or EVP_PKEY_set1_RSA() 如果还使用了 EVP_PKEY_free,C++ OpenSSL RSA_free 会出现分段错误 - C++ OpenSSL RSA_free give Segmentation fault if EVP_PKEY_free is also used OpenSSL 上的错误“不完整 class 类型‘evp_pkey_st’是不允许的”和“‘CRYPTO_mem_leaks’未定义” - Errors "incomplete class type 'evp_pkey_st' is not allowed" and "'CRYPTO_mem_leaks' is undefined" on OpenSSL 如何使用 openssl EVP 解密? - How to decrypt using openssl EVP?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM