X509证书实质是公钥和与之相关的拥有者和签发者的一个打包。因此,为了创建一个证书请求,必须先产生一个公私密钥对。 X.509 证书在 openssl 中是用 X509_REQ 对象表示的。证书请求中主要包括密钥对中的公钥部分,除此之外还包括 subjectName 字段和其他一些 X.509 的属性。这些属性对于证书请求来说是可选参数,但是 subject name 却是必须有的。
X509_NAME对象类型代表证书的名称。具体说来证书请求只包含 subject name ,但是完整的证书包含 subject 和 issuer name 。设置名称字段目的是为了完整地标识一个实体 -- 一台服务器,某个人,或者一家公司等等。对于这些实体,名称字段包括多个条目比如 country name , organization name 和 common name 等。
理论上在名称中可以包含任意的字段,但实际上有一些标准规定。在oenssl 内部通过一个整数来标识字段,也就是 NID 。
如前所述,证书名称是由X509_NAME对象表示的。该对象实质是X509_NAME_ENTRY对象的集合。每一个 X509_NAME_ENTRY对象代表了名称中一个字段及其相应的内容值。因此,需要为每一个字段创建 X509_NAME_ENTRY 对象,然后将之放入证书请求的名称字段中。首选查找需要创建的字段的NID ,通过 NID 创建 X509_NAME_ENTRY 对象并添加数据,然后将该字段条目加入 X509_NAME 中,如此重复直到组装好名称字段后,就可以添加到 X509_REQ 对象中。
X509 V3扩展项
SSL中非常有用的一个扩展是 subjectAltName 。该扩展包含一个 dNSName 的字段,这个字段包含了终端实体处理证书需要的 FQDN 。在发送证书请求给 CA 制作证书之前,有必要先添加扩展项。
X509_EXTENSION类型对象代表了 X509 对象内部的单项扩展条目。添加扩展的过程简言之是把所有要求的扩展项添加到 STACK_OF(X509_EXTENSION) 对象中,再将该 STACK 加入到证书请求中即可。
回顾一下创建证书请求:首先创建X509_REQ 对象,为之添加一个 subject name 和公钥,添加所有需要的扩展项,最后使用私钥对请求进行签名。为了表示公钥和私钥组成部分,这里使用通用EVP_KEY类型以及相应的函数。Openssl中消息摘要算法是通过 EVP_MD 对象表示的。基于要签发 key 的类型--RSA或者DSA ,我们需要制定不同的 EVP_MD 对象。但是在签名时候并不知道公钥算法,因此必须使用抽象 EVP_PKEY 接口。可以通过探究 EVP_PKEY 对象内部知道其算法。。。。( 这一段不甚明了。)
使用合适的PEM调用来读取私钥。公钥是私钥中信息的一个子集( a public key is a subset of the information in a private key )。