我用我的项目公钥/私钥加密/解密的一些数据。
我在服务器上托管的公钥(“public.pem”)。
“public.pem”看起来是这样的:
-----BEGIN PUBLIC KEY-----
.....
.....
-----END PUBLIC KEY-----
我写了这个下载公共密钥并将其保存到磁盘上的客户端,然后调用OpenSSL的PEM_read_RSA_PUBKEY()的文件描述符到该文件。 此操作的伟大工程,结果是一个RSA对象,已准备好进行加密。
我想,以避免每次都写公开密钥盘(因为我在内存有缓冲的话)。
我该怎么办,不保存中buffer to disk相同的操作? 我注意到一个调用的函数:)PEM_read_bio_RSAPublicKey(但我不知道它是BIO结构的使用。 我在正确的道路上?
所以真正的问题是:我读了公钥/私钥到RSA对象直接从内存中,而不是从一个文件描述符怎么办。
你是在正确的轨道上。 您必须已经由BIO缓冲的方式通过包裹PEM密钥存储BIO_new_mem_buf()
换句话说,是这样的:
BIO *bufio;
RSA *rsa
bufio = BIO_new_mem_buf((void*)pem_key_buffer, pem_key_buffer_len);
PEM_read_bio_RSAPublicKey(bufio, &rsa, 0, NULL);
同样的方法是有效的RSA私钥(通过PEM_read_bio_RSAPrivateKey
),但在这种情况下,你肯定需要照顾的密码。 检查手册页了解详情。
SquareRootOfTwentyThree的方法对我不起作用。 这里是我的解决方案。
BIO* bio = BIO_new(BIO_s_mem());
int len = BIO_write(bio, pem_key_buffer, pem_key_buffer_len);
EVP_PKEY* evp_key = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL);
RSA* rsa = EVP_PKEY_get1_RSA(evp_key);
下面是完整的例子,显示嵌入式键,以及如何使用C ++ 11个唯一指针来管理OpenSSL的资源。
更新:从下面的评论上spectras 。 不再使用的专业化default_delete<T>.
/* compile with:
c++ -Wall -pedantic -std=c++17 main.cc -lssl -lcrypto -o main
*/
#include <memory>
#include <iostream>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <assert.h>
#include <string.h>
/* Custom deletors for use with unique_ptr */
struct EVP_PKEY_deleter {
void operator()(EVP_PKEY* p) const {
if (p)
EVP_PKEY_free(p);
}
};
struct BIO_deleter {
void operator()(BIO* p) const {
if (p)
BIO_free(p);
}
};
/* Smart pointers wrapping OpenSSL resources */
using evp_key_ptr = std::unique_ptr<EVP_PKEY, EVP_PKEY_deleter>;
using bio_ptr = std::unique_ptr<BIO, BIO_deleter>;
/* Create key based on memory contents */
evp_key_ptr load_public_key(const char* buf, size_t len)
{
bio_ptr bp (BIO_new_mem_buf((void*) buf, len));
if (!bp)
throw std::runtime_error("BIO_new_mem_buf failed");
EVP_PKEY * kp = nullptr;
kp = PEM_read_bio_PUBKEY(bp.get(), &kp, nullptr, nullptr);
ERR_print_errors_fp(stderr);
return evp_key_ptr{kp};
}
int main()
{
const char * RSA_PUBLIC_KEY=R"(
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA80ZqDPPW5eOH6TWdLsEJ
8qf6hoMJfFZ3BL9Fz+YNGeBpF3zxKmm8UuRrBHHVZZB2Gs1MTo06IU3fqDfFsOyh
J6pHeJF3wyUlYZuYbGAyMlZZ/+M5TOvo92f7lt/A40QThCVf1vS5o+V8sFkgnz3N
C7+VvC4dYrv+fwnmnWGxPy1qfp3orB+81S4OPRiaoy+cQBZs10KCQaNBI/Upzl2R
3dMkWKM+6yQViKTHavT4DRRZ1MKp9995qOR3XfhhJdWuDl4moXcU3RcX4kluvS5q
b8oTnVyd2QB1GkUw6OKLWB/5jN1V1WzeYK447x2h4aPmJfsn5gCFJs6deq2RFQBR
SQIDAQAB
-----END PUBLIC KEY-----
)";
ERR_load_crypto_strings();
ERR_free_strings();
auto pubkey = load_public_key(RSA_PUBLIC_KEY, strlen(RSA_PUBLIC_KEY));
if (pubkey)
std::cout << "load_public_key success" << std::endl;
}