[英]How to read an RSA public key from a its PEM format string using the OpenSSL API?
I could use the PEM_read_RSA_PUBKEY
function to easily read a PEM file . 我可以使用
PEM_read_RSA_PUBKEY
函数轻松读取PEM 文件 。 However, I have a public key that I have built into the executable and I would prefer not to make a temporary file. 但是,我有一个公钥,我已经内置到可执行文件中,我宁愿不制作一个临时文件。 Reading on this example/tutorial: http://hayageek.com/rsa-encryption-decryption-openssl-c/ I came up with the following solution:
阅读这个示例/教程: http : //hayageek.com/rsa-encryption-decryption-openssl-c/我提出了以下解决方案:
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/bio.h>
#include <QFile>
#include <QByteArray>
#include <stdexcept>
#include <cassert>
#include <cstring>
RSA* createRSA(const char* key)
{
RSA *rsa = nullptr;
BIO *keybio ;
keybio = BIO_new_mem_buf(key, -1); // !!!
if (!keybio)
{
throw std::runtime_error("Failed to create key BIO");
}
rsa = PEM_read_bio_RSA_PUBKEY(keybio, nullptr, nullptr, nullptr); // !!!
if(!rsa )
{
throw std::runtime_error("Failed to create RSA");
}
BIO_free(keybio); // !!!
return rsa;
}
int main()
{
QFile publicKeyFile(":/public.pem");
publicKeyFile.open(QIODevice::ReadOnly);
auto data = publicKeyFile.readAll();
RSA* rsa = createRSA(data.data());
EVP_PKEY* verificationKey = EVP_PKEY_new();
auto rc = EVP_PKEY_assign_RSA(verificationKey, RSAPublicKey_dup(rsa));
assert(rc == 1);
if(verificationKey)
EVP_PKEY_free(verificationKey);
return 0;
}
However I have a lot of doubts: 但是我有很多疑问:
BIO_new_mem_buf
takes a const void*
parameter, can I just pass a const char*
? BIO_new_mem_buf
采用const void*
参数,我可以只传递一个const char*
吗? I did not figure it out even from the docs . PEM_read_bio_RSA_PUBKEY
function, the original example calls it like this: rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa,NULL, NULL);
PEM_read_bio_RSA_PUBKEY
函数时,原始示例将其调用如下: rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa,NULL, NULL);
which I do not understand even after reading the docs . nullptr
as the second argument. nullptr
作为第二个参数传递。 RSA_free
on the returned RSA
pointer? RSA
指针上调用RSA_free
吗? valgrind
does not see a memory leak whether I do it or not. valgrind
都没有看到内存泄漏。 BIO_free(keybio);
BIO_free(keybio);
after I am done with the BIO
? BIO
? valgrind
sees a memory leak if I do not, and in the tutorial this call was missing. valgrind
看到内存泄漏,并且在教程中这个调用丢失了。 If I call BIO_free(keybio);
BIO_free(keybio);
it would imply that PEM_read_bio_RSA_PUBKEY
copied the data from the BIO
rather than just linking to it. PEM_read_bio_RSA_PUBKEY
从BIO
复制数据而不是仅仅链接到它。 But if that were the case, shouldn't I free the RSA
? RSA
吗? Any advice is warmly appreciated. 任何建议都热烈赞赏。 I do not know what is real anymore.
我不知道什么是真实的。
Answers to each of your questions: 您的每个问题的答案:
const char*
, it is cast. const char*
,它是强制转换的。 PEM_read_bio_RSA_PUBKEY
creates allocates the RSA structure for you. PEM_read_bio_RSA_PUBKEY
创建为您分配RSA结构。 The argument (if not null) is used to store the pointer to it, which will be the same as the return value. 参数(如果不为null)用于存储指向它的指针,该指针与返回值相同。 It is used for simplified coding:
if (!PEM_read_bio_RSA_PUBKEY(keybio, &rsa, nullptr, nullptr)) { /* error */ }
它用于简化编码:
if (!PEM_read_bio_RSA_PUBKEY(keybio, &rsa, nullptr, nullptr)) { /* error */ }
Yes, you have to release it using RSA_free
. 是的,你必须使用
RSA_free
释放它。
PS: OpenSSL documentation is a bit tricky because there are many similar functions that only vary in algorithm, structures or data format. PS:OpenSSL文档有点棘手,因为有许多类似的函数只在算法,结构或数据格式上有所不同。 At the end of the man page there is a Description section where they are explained, removing the specifics of each variation.
在手册页的末尾有一个描述部分,在这里解释它们,删除每个变体的细节。 But yes, it is quite difficult to find it out with out a good tutorial or examples.
但是,是的,通过一个很好的教程或例子很难找到它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.