前面分析过加解密、证书与安全通信之间的关联关系,现在换个角度来剖析证书的制作与其本质。我们先构建一个CA环境,生成CA密钥、制作CA证书请求、自签名等,然后通过自建的CA来签发用户证书。
准备工作
通过命令查询openssl的环境信息,主要是确认openssl的配置路径信息OPENSSLDIR。
命令:openssl version -a
可以看到openssl的配置路径在/usr/lib/ssl/,那么当下使用的openssl默认配置信息就是该目录下的openssl.cnf。打开该文件找到ca相关的信息。
命令:vim /usr/lib/ssl/openssl.cnf
我们需要通过上面看到的信息构建CA环境,工作目录demoCA,以及在该目录下的私钥目录private和新证书目录newcerts,创建索引文件以及序列号文件信息。如下命令可以完成该事情。
创建好之后可以看到该结构:
同时我们构建自己的CA证书命名和保存路径也要遵循配置信息,譬如:CA私钥要命名为cakey.pem且放在demoCA/private路径下,CA证书要命名为cacert.pem且要放在demoCA下。因为我们最终要签发的是服务证书,所以要遵循openssl的CA配置,当然可以通过命令参数进行指定CA信息,但是由于会对我们分析证书的制作有影响,所以命令行的参数能省则省。
CA证书制作
制作证书前,我们需要先生成CA的私钥,为什么不是公钥和私钥一起的密钥对呢?实际上加解密算法的私钥都是可以通过公钥进行算出来的。
命令:openssl genrsa -out ./demoCA/private/cakey.pem 1024
生成好CA私钥cakey.pem之后,我们打开来看看里面的内容。似乎是一脸茫然,这是什么鬼?这是通过ASN.1编码后的公钥信息,ASN.1编码是一种独立于计算机架构和语言的方式来描述数据结构。
里面的信息通过解码可以看到具体的内容,可以通过下面的命令看到内容,顺便可以通过-pubout参数看到该私钥相对应的公钥。
命令:openssl rsa -in ./demoCA/private/cakey.pem -text -pubout
里面的公钥信息。
拥有了私钥之后,我们可以通过私钥生成证书请求。
命令:openssl req -new -days 3650 -key ./demoCA/private/cakey.pem -out ./demoCA/private/careq.pem
证书请求生成的过程中需要我们填入国家、省市地区以及组织等用于确认身份的信息。甚至可以选择加入证书加强密码等,为了简便起见,密码我们就不填了。
同样,打开证书请求,可以看到内容也是以ASN.1进行编码的。
但是我们可以通过openssl展开里面的内容描述。
命令:openssl req -in ./demoCA/private/careq.pem -noout -text -pubkey
可以看到里面有我们填入的身份信息以及密钥相关的信息,同样可以看到完整的公钥也带入到了证书请求当中。接下来我们对证书请求进行自签发操作,因为CA证书只能够自己给自己签发。
命令:openssl ca -selfsign -in ./demoCA/private/careq.pem -out ./demoCA/cacert.pem
打开证书看一下,这就是证书格式,拥有版本号、序列号、签发者信息、有效时间、拥有者信息以及密钥信息等内容。
似乎没有公钥信息?是的,被隐藏起来了,在下面CERTIFICATE的BEGIN和END之间的ASN.1编码中,没有显式记录在证书当中,不过我们可以通过命令来查看。
命令:openssl x509 -in ./demoCA/cacert.pem -pubkey -noout
至此,我们创建好了CA的密钥以及自签发了证书。
用户证书制作
用户证书的制作流程和CA证书的制作是一样的,只是CA是自签发动作,而用户证书是由CA使用私钥签发而已。先是生成证书私钥,还是用同样的命令genrsa,但是我们特地加了-des3参数。那么在制作的过程中,它会提示我们需要输入密码,这里选择使用密码123123。
命令:openssl genrsa -des3 -out ./demoCA/private/srvkey.pem 2048
那么打开生成的私钥,可以看到有明显的不同,这里指示了当前KEY是经过加密的,加密算法为DES-EDE3-CBC。
它和前面生成CA私钥的区别在于我们如果需要查看或者使用该私钥时,需要输入密码。其实正确的用法是需要对私钥进行加密的,以达到足够的保护。此外,我们这次生成的私钥用的是2048的长度,所以密钥看起来也长了(废话)。
有了私钥,然后就是生成证书请求,为了明显和CA证书拉开差异,生成证书请求时,我们构造用户为美国硅谷的Apple公司,Banana部门,通用名为cat。而我们前面构造的CA证书是CN中国的JeanLeo公司,Leo部门及通用名为Jean。
命令:openssl req -new -days 3650 -key ./demoCA/private/srvkey.pem -out ./demoCA/srvreq.pem
生成的证书请求内容我们就不展开了,因为和前面CA的证书请求大同小异。但是也因为这个构造用户,我们需要修改了openssl.cnf配置文件,将证书签发策略改了,即policy,改成policy_anything。也就是我们签发用户证书时,不需要对国家、省市及组织的标示信息与CA的保持一致。
否则如果在policy是policy_match的情况下,我们签发证书是会报错的。
命令:openssl ca -days 3650 -in ./demoCA/srvreq.pem -out ./srvcert.pem
如果修改之后,将会成功签发用户证书。
而签发的证书可以看到里面签发者的国家信息是CN,用户的国家信息是US和我们前面的证书请求是一致的。
就这样用户证书签发好了,至于证书的公钥也和CA的一样,是来自用户私钥,这里就不演示了。所以证书也不过如此罢了。