编程方式创建X509Certificate使用OpenSSL
-
05-07-2019 - |
题
我有一个C/C++应用程序和我需要建立一个X509pem证书同时包含公共和私人钥匙。该证书可以是自签署、或未签名的,没问题。
我想要做这个的内部程序,不从命令行。
什么OpenSSL functions会这么做为我?任何代码样本是一个奖金!
解决方案
您首先需要熟悉术语和机制。
根据定义,X.509 证书不包含私钥。相反,它是公钥的CA签名版本(以及CA放入签名的任何属性)。 PEM格式实际上只支持密钥和证书的单独存储 - 尽管您可以将两者连接起来。
在任何情况下,您都需要调用OpenSSL API的20多个不同功能来创建密钥和自签名证书。一个例子是OpenSSL源本身,在演示/ X509 / mkcert.c
如需更详细的解答,请参阅下面的 Nathan Osman的解释。
其他提示
我意识到这是一个非常晚(和很长)的答案。但考虑到这个问题在搜索引擎结果中的排名有多好,我认为可能值得写一个体面的答案。
下面你要阅读的很多内容都来自此演示和OpenSSL文档。以下代码适用于C和C ++。
在我们实际创建证书之前,我们需要创建一个私钥。 OpenSSL提供 EVP_PKEY
结构,用于在内存中存储与算法无关的私钥。这个结构在 openssl / evp.h
中声明,但是由 openssl / x509.h
(后面我们将需要)包含在内,所以你真的不需要显式包含标题。
为了分配 EVP_PKEY
结构,我们使用 <代码> EVP_PKEY_new 代码> :
EVP_PKEY * pkey;
pkey = EVP_PKEY_new();
还有一个用于释放结构的相应函数 - EVP_PKEY_free
- 它接受一个参数:上面初始化的 EVP_PKEY
结构。
现在我们需要生成一个密钥。对于我们的示例,我们将生成RSA密钥。这是通过 RSA_generate_key
函数完成的在 openssl / rsa.h
中。此函数返回指向 RSA
结构的指针。
对函数的简单调用可能如下所示:
RSA * rsa;
rsa = RSA_generate_key(
2048, /* number of bits for the key - 2048 is a sensible value */
RSA_F4, /* exponent - RSA_F4 is defined as 0x10001L */
NULL, /* callback - can be NULL if we aren't displaying progress */
NULL /* callback argument - not needed in this case */
);
如果 RSA_generate_key
的返回值为 NULL
,则出现问题。如果没有,那么我们现在有一个RSA密钥,我们可以将它分配给我们之前的 EVP_PKEY
结构:
EVP_PKEY_assign_RSA(pkey, rsa);
释放 EVP_PKEY
结构时,将自动释放 RSA
结构。
现在是证书本身。
OpenSSL使用 X509
结构在内存中表示x509证书。此结构的定义位于 openssl / x509.h
中。我们需要的第一个功能是 X509_new
。它的用途相对简单:
X509 * x509;
x509 = X509_new();
与 EVP_PKEY
的情况一样,有一个用于释放结构的相应函数 - X509_free
。
现在我们需要使用一些 X509 _ *
函数设置证书的一些属性:
ASN1_INTEGER_set(X509_get_serialNumber(x509), 1);
这会将证书的序列号设置为“1”。某些开源HTTP服务器拒绝接受序列号为“0”的证书,这是默认值。下一步是指定证书实际有效的时间跨度。我们通过以下两个函数调用来实现:
X509_gmtime_adj(X509_get_notBefore(x509), 0);
X509_gmtime_adj(X509_get_notAfter(x509), 31536000L);
第一行将证书的 notBefore
属性设置为当前时间。 ( X509_gmtime_adj
函数将指定的秒数添加到当前时间 - 在本例中为none。)第二行将证书的 notAfter
属性设置为从现在开始的365天(60秒* 60分钟* 24小时* 365天)。
现在我们需要使用之前生成的密钥为我们的证书设置公钥:
X509_set_pubkey(x509, pkey);
由于这是一个自签名证书,我们将发行者的名称设置为主题的名称。该过程的第一步是获取主题名称:
X509_NAME * name;
name = X509_get_subject_name(x509);
如果您之前曾在命令行上创建过自签名证书,则可能记得被要求提供国家/地区代码。这是我们提供它以及组织('O')和通用名称('CN'):
X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC,
(unsigned char *)"CA", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC,
(unsigned char *)"MyCompany Inc.", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
(unsigned char *)"localhost", -1, -1, 0);
(我在这里使用价值'CA',因为我是加拿大人,那是我们的国家
任何机会这样做过 system
电话在你的程序?几个良好的理由这样做:
许可证:叫
openssl
可执行可以说,将其分离,从你的应用程序和可提供某些优势。 免责声明:向律师咨询这一点。文件:OpenSSL附带 惊人的 命令行文档,极大地简化了潜在的复杂工具。
可测性:你可以行使OpenSSL从命令行,直到你完全了解如何创建证书.还有一个 很多 选项;预期花费大约一天在这直到你得到的所有详细信息的权利。在这之后,它是平凡的合并命令进入你的应用程序。
如果你选择使用API,检查 openssl-dev
开发人员名单上www.openssl.org.
祝你好运!
非常简单的教程,以创建数字证书 http://publib.boulder.ibm.com/infocenter/rsthelp/v8r0m0/index.jsp?topic=/com.ibm.rational.test.lt.doc/topics/tcreatecertopenssl.html
关于执行这些命令代码中我不知道。