使用OpenSSL以编程方式创建X509证书

使用OpenSSL以编程方式创建X509证书,openssl,ssl-certificate,x509,pkix,Openssl,Ssl Certificate,X509,Pkix,我有一个C/C++应用程序,需要创建一个包含公钥和私钥的X509 pem证书。证书可以是自签名的,也可以是未签名的,这无关紧要 我想在应用程序中执行此操作,而不是从命令行 什么OpenSSL函数可以为我做到这一点?任何示例代码都是奖励 有没有可能通过应用程序内的系统呼叫来执行此操作?这样做有几个很好的理由: 许可:调用openssl可执行文件可以将其与应用程序分开,并可能提供某些优势。免责声明:就此咨询律师 文档:OpenSSL附带了出色的命令行文档,大大简化了一个潜在的复杂工具 可测试性:您

我有一个C/C++应用程序,需要创建一个包含公钥和私钥的X509 pem证书。证书可以是自签名的,也可以是未签名的,这无关紧要

我想在应用程序中执行此操作,而不是从命令行


什么OpenSSL函数可以为我做到这一点?任何示例代码都是奖励

有没有可能通过应用程序内的
系统
呼叫来执行此操作?这样做有几个很好的理由:

  • 许可:调用
    openssl
    可执行文件可以将其与应用程序分开,并可能提供某些优势。免责声明:就此咨询律师

  • 文档:OpenSSL附带了出色的命令行文档,大大简化了一个潜在的复杂工具

  • 可测试性:您可以在命令行中使用OpenSSL,直到您完全理解如何创建证书。有很多选择;在你把所有细节都弄清楚之前,你要花大约一天的时间来做这件事。之后,将该命令合并到应用程序中就变得很简单了

如果选择使用API,请查看www.openssl.org上的
openssl dev
developers'列表


祝你好运

您首先需要熟悉术语和机制

根据定义,X.509证书不包括私钥。相反,它是公钥的CA签名版本(以及CA放入签名中的任何属性)。PEM格式实际上只支持密钥和证书的单独存储,尽管您可以将两者连接起来

在任何情况下,您都需要调用OpenSSL API的20多个不同函数来创建密钥和自签名证书。OpenSSL源代码本身就是一个例子


有关更详细的答案,请参见下文。

我意识到这是一个很晚(很长)的答案。但考虑到这个问题在搜索引擎结果中的排名有多高,我想也许值得为它写一个像样的答案

您将在下面阅读的许多内容都是从OpenSSL文档和OpenSSL文档中借来的。下面的代码适用于C和C++。
在实际创建证书之前,我们需要创建私钥。OpenSSL提供了
EVP_PKEY
结构,用于在内存中存储与算法无关的私钥。此结构在
openssl/evp.h
中声明,但包含在
openssl/x509.h
中(稍后我们将需要它),因此您实际上不需要显式包含标头

为了分配一个
EVP_PKEY
结构,我们使用:

EVP_PKEY*PKEY;
pkey=EVP_pkey_new();
还有一个用于释放结构的相应函数-
EVP\u PKEY\u free
,它接受一个参数:上面初始化的
EVP\u PKEY
结构

现在我们需要生成一个密钥。对于我们的示例,我们将生成一个RSA密钥。这是通过
openssl/rsa.h
中声明的函数完成的。此函数返回指向
RSA
结构的指针

函数的简单调用可能如下所示:

RSA*RSA;
rsa=rsa\u生成\u密钥(
2048,/*键的位数-2048是一个合理的值*/
RSA_F4,/*指数-RSA_F4定义为0x10001L*/
NULL,/*callback-如果不显示进度,则可以为NULL*/
NULL/*回调参数-在这种情况下不需要*/
);
如果
RSA\u generate\u key
的返回值为
NULL
,则表示出现了问题。如果没有,那么我们现在有了一个RSA密钥,我们可以将它分配给前面的
EVP_PKEY
结构:

EVP_PKEY_assign_RSA(PKEY,RSA);
当释放
EVP_PKEY
结构时,
RSA
结构将自动释放


现在是证书本身

OpenSSL使用
X509
结构来表示内存中的X509证书。此结构的定义在
openssl/x509.h
中。我们需要的第一个功能是。它的使用相对简单:

X509*X509;
x509=x509_new();
EVP_PKEY
的情况一样,有一个相应的函数用于释放结构-
X509_free

现在,我们需要使用一些
X509.*
函数设置证书的一些属性:

ASN1\u整数集(X509\u get\u serialNumber(X509),1);
这将证书的序列号设置为“1”。某些开源HTTP服务器拒绝接受序列号为“0”的证书,这是默认值。下一步是指定证书实际有效的时间跨度。我们通过以下两个函数调用来实现这一点:

X509\u gmtime\u adj(X509\u get\u notBefore(X509),0);
X509_gmu time_adj(X509_get_notAfter(X509),31536000L);
第一行将证书的
notBefore
属性设置为当前时间。(函数的
X509_gmtime_adj
将指定的秒数添加到当前时间(在本例中为无)。第二行将证书的
notAfter
属性设置为从现在起365天(60秒*60分钟*24小时*365天)

现在,我们需要使用前面生成的密钥设置证书的公钥:

X509\u set\u pubkey(X509,pkey);
由于这是一个自签名证书,我们将颁发者的名称设置为主体的名称。该过程的第一步是获取主题名称:

X509_NAME*NAME;
name=X509\u get\u subject\u name(X509);
如果您以前在命令行上创建过自签名证书,您可能还记得有人要求您输入国家代码。在这里,我们提供了它以及组织(“O”)和通用名称(“CN”):

X5