有人可以分享一个使用 openssl 3.0 c++ 库生成密钥对的简单示例吗?官方网站不好,很多功能已弃用,但仍然列出在那里,gpt 生成的代码失败了
EVP_PKEY_copy_parameters
。这是我从 gpt 得到的代码,它不起作用。
#include <iostream>
#include <memory>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <string>
#include <vector>
// Custom deleter for EVP_PKEY
struct EVP_PKEY_Deleter {
void operator()(EVP_PKEY *pkey) const { EVP_PKEY_free(pkey); }
};
// Type alias for unique_ptr with EVP_PKEY and custom deleter
using Key = std::unique_ptr<EVP_PKEY, EVP_PKEY_Deleter>;
std::pair<Key, Key> generate_rsa_keys() {
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, nullptr);
if (!ctx) {
throw std::runtime_error("Failed to create context");
}
EVP_PKEY *pkey_raw = EVP_RSA_gen(2048);
if (!pkey_raw) {
EVP_PKEY_CTX_free(ctx);
throw std::runtime_error("Key generation failed");
}
EVP_PKEY *public_key_raw = EVP_PKEY_new();
if (!public_key_raw) {
EVP_PKEY_free(pkey_raw);
EVP_PKEY_CTX_free(ctx);
throw std::runtime_error("Failed to create public key");
}
if (EVP_PKEY_copy_parameters(public_key_raw, pkey_raw) <= 0) {
EVP_PKEY_free(pkey_raw);
EVP_PKEY_free(public_key_raw);
EVP_PKEY_CTX_free(ctx);
throw std::runtime_error("Failed to copy parameters");
}
Key pkey(pkey_raw);
Key public_key(public_key_raw);
return {std::move(pkey), std::move(public_key)};
}
int main() {
auto [pkey, public_key] = generate_rsa_keys();
}
在文档中查找所有内容有点棘手,但最终新 API 所需的编码比已弃用的 API 略少。您可以例如请按照以下步骤操作:
EVP_RSA_gen(unsigned int bits);
生成 RSA 密钥对EVP_PKEY_print_public
(或任何其他版本:private、params)将公钥打印到 BIO
I/O 结构BIO_read
将人类可读的信息复制到某些 char*
缓冲区完整示例(没有错误检查):
constexpr size_t kBits = 1024;
int main() {
EVP_PKEY* key = EVP_RSA_gen(kBits);
BIO* bio = BIO_new(BIO_s_mem());
EVP_PKEY_print_public(bio, key, 4, nullptr);
// I hardcoded 2056, because I'm lazy, but probably there is some way to query the number of available bytes from BIO
std::string keyStr(2056, 0);
std::cout << "num bytes read: " << BIO_read(bio, keyStr.data(), keyStr.size()) << std::endl;
std::cout << "keyStr: " << keyStr << std::endl;
BIO_free_all(bio);
EVP_PKEY_free(key);
}