目前,我正在为OpenSSL C++ API而奋斗。我使用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在我自己的机器上加密消息时,没有问题。解密过程也一样。我只是将键区作为SealInit / OpenInit函数的一个参数。
但考虑一下,我想生成一个键盘,并将公钥或私钥作为字符发送给另一个人:我如何做到这一点?
我在互联网上找到的一种方法是使用PEM_write_bio_PUBKEY或PEM_write_bio_PrivateKey将密钥转换为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*,以便在函数中使用它。有什么建议吗?
发布于 2017-11-01 13:56:12
但考虑一下,我想生成一个键盘,并将公钥或私钥作为字符发送给另一个人:我如何做到这一点?
您需要用于序列化和连线格式或演示格式的东西。您的公钥和加密消息可能具有0字符,这些字符以嵌入式NULL的形式出现。因此,您需要有一个缓冲区和显式长度。
使用谷歌的ProtocolBuffers,二进制JSON,甚至ASN.1/DER编码。我认为谷歌的ProtocolBuffers是面向消息的,所以他们不会返回一个消息,直到完整的消息是可用的。
您还可以对其进行十六进制、Base32或Base64编码。但你仍然需要沟通一个长度,以便接收方知道他们得到了整个信息。在本地局域网上,您可能永远不会遇到问题。在互联网上,你可能偶尔会遇到失败,因为你偶尔会做一些简短的阅读。
您对PEM_write_bio_PUBKEY的想法实际上是Base64编码密钥,因此它面临着与十六进制、Base32或Base64编码相同的潜在问题。
如何将char*转换回EVP_PKEY
根据上面的更改,您可能不会使用char*。一旦你改进了设计,你可能会问一个新的问题。
但是现在,如果您用PEM_write_bio_PUBKEY和PEM_write_bio_PrivateKey保存了密钥,那么您将分别使用PEM_read_bio_PUBKEY或PEM_read_bio_PrivateKey。还请参阅OpenSSL的手册页。
与C++相关的是,下面是使用OpenSSL时的一些技巧。如果您正在使用C++11,那么unique_ptr确实使处理一些OpenSSL对象变得非常容易。
https://stackoverflow.com/questions/47045979
复制相似问题