1. 制作前搞清楚一些概念
(1)何为CA服务器
CA服务器,一般也叫作证书服务器,Linux和Windows上都有相应的证书服务器软件,Cisco iOS也可以用作CA。证书的申请可以离线申请,也可以在线申请。
离线申请就是申请者提交CSR文件给CA时,走带外,例如复制粘贴。在线申请则是申请者通过SCEP协议带内发送CSR文件给CA。
openssl不支持在线申请,Windows和Cisco iOS都支持在线申请。本文以Linux(Ubuntu18.04)上的openssl来充当证书服务器,用来给证书申请者签发证书,一般Linux默认安装好了openssl程序。
(2)CA服务器的级别
CA服务器其实也是分等级的,比如RootCA,SubCA,Sub.SubCA,....直到最终的用户证书,这其实也构成了我们通常说的证书链,至于为何是这样,可以查阅PKI体系的相关资料。
每一级CA的证书都是由它直属的上级CA来颁发的,RootCA由于没有上一级,所以它的证书就是由自己签发的。现在一般的证书里面都带了一个扩展字段,用于指明该证书是否可以作为CA,当然除了这个以外,还有好多功能,下文会提及到。
(3)证书extensions字段介绍
在证书中,除了必要的字段(比如Issure,Subject...)外,还包含了一个叫做extensions的字段。
extensions里面内容很多,正式因为extensions,带给了我们证书的丰富性,解决了不少问题。
例如可以指明证书的用途,可以指明证书是否可以作为CA,给其他人签发证书,可以让该证书给多人使用,也就是我们所说的多域名证书。
(4)openssl与extensions字段的关系
openssl颁发证书时候,可以给证书加上一些extensions字段,以此为证书提供丰富的特性。
当然openssl在制作CSR时,也可以给CSR加上extensions字段,最终为根据此CSR生成的证书提供丰富的特性。
(5)openssl为申请者颁发证书流程
关于证书颁发流程可以通过,一条命令即可判断,看这条命令的输入参数有哪些,这些参数的输入值,是需要提前准备。
openssl ca //颁发证书的命令
-cert RootCA.pem //颁发者的证书,即直属CA的证书
-keyfile RootCA.key //颁发者的私钥,即直属CA的私钥
-in common.csr //被颁发证书的CSR文件
-days 3650 //被颁发证书的有效期
-md sha256 //被颁发证书的签名算法
-extensions usr_cert //被颁发证书的扩展字段
-out common.pem //被颁发的证书,即我们申请的证书,作为输出参数
2. 利用openssl为申请者颁发证书
2.1 在原来的目录/etc/ssl/下新建demoCA/目录及其子目录
所有命令都在路径/etc/ssl/目录下以root权限执行
su -
cd /etc/ssl/
此步骤的目的, 是为了解决调用openssl ca命令时报错, 无法继续下一步.
mkdir -p demoCA/newcerts
touch demoCA/index.txt
touch demoCA/index.txt.attr
touch demoCA/serial
echo "0001" > demoCA/serial
2.2 修改openssl.cnf文件里的section [policy_match]
建议修改成如下所示
========================================================================
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy = policy_match
# For the CA policy
[ policy_match ]
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
说明: 在CA给CSR签名产生证书时, 会比较CA证书和CSR文件里面的字段是否满足匹配策略
========================================================================
比较的字段如下:
counrtyName, stateOrProvinceName, organizationName,
organiztionUnitName, commonName, emailAddress
匹配的策略有match, optional, supplied, 三者的意思如下:
match:表示CA证书和申请者CSR对应字段必须相同,
optional:则可不相同,
supplied:则是必须不同,且不同为空
目的:以防出现以下问题
==========================================================================
Using configuration from /usr/lib/ssl/openssl.cnf
Check that the request matches the signature
Signature ok
The organizationalUnitName field is different between
CA certificate (UCTG) and the request (CRDC)
2.3 搭建RootCA服务器
(1)执行下列命令,生成RSA公私钥对和CSR
openssl genrsa -out RootCA.key 2048
openssl req -key RootCA.key -out RootCA.csr -new -sha256
(2)查看需调用openssl.cnf文件的section [ v3_ca ]【此步骤可选】
[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical,CA:true
(3)执行以下命令给RootCA自签发证书
openssl ca -selfsign -in RootCA.csr -keyfile RootCA.key -out RootCA.pem -days 3650 -md sha256 -extensions v3_ca
(4)查看RootCA的key、CSR、自签发证书【此步骤可选】
openssl key -in RootCA.key -text
openssl req -in RootCA.csr -text
openssl x509 -in RootCA.pem -text
2.4 搭建SubCA服务器
(1)给SubCA生成key、CSR
openssl genrsa -out SubCA.key 2048
openssl req -key SubCA.key -out SubCA.csr -new -sha256
(2)确认SubCA的直属上级CA,也就是RootCA的证书和key都存在(上一步已经提前生成)
ls -l RootCA*
-rw-r--r-- 1 root root 1013 Apr 10 17:22 RootCA.csr
-rw-r--r-- 1 root root 1675 Apr 10 14:06 RootCA.key
-rw-r--r-- 1 root root 4333 Apr 10 17:28 RootCA.pem
(3)在openssl.cnf文件里新增section [ v3_ica ]
[ v3_ica ]
basicConstraints = critical, CA:TRUE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always, issuer:always
keyUsage = critical, cRLSign, digitalSignature, keyCertSign
subjectAltName = @alt_ica
[ alt_ica ]
DNS.1 = SubCA.crdc.cisco.com
IP.1 = 10.74.97.122
(4)执行以下命令,给SubCA签发证书
openssl ca -cert RootCA.pem -keyfile RootCA.key -in SubCA.csr -out SubCA.pem -days 3650 -md sha256 -extensions v3_ica
2.5 签发用户证书
2.5.1 颁发普通证书 【如果初次制作证书,就参考此步骤】
(1)上传CSR文件到openssl指定的目录
ubuntu下建议为/etc/ssl/,centos下建议/etc/pki/tls/,可以通过ftp、ssh、scp、复制粘贴等等各种方式,上传申请者CSR文件到CA服务器。
CSR的内容里面可能携带有extensions,这些extensions一般说明该CSR的用途,别名,是否可以作为CA等等信息。
(2)选择直属上级CA的证书和key
在上文中已经制作好了RootCA和SubCA的证书和key,根据你的需求:是需要两级证书,还是三级证书,选择其中一个CA的证书和key,来签发证书即可。两级证书,就选择RootCA,三级证书就选择SubCA。
(3)查看需调用的section [ usr_cert ]【此步骤可选】
[ usr_cert ]
basicConstraints=CA:FALSE
nsComment = "OpenSSL Generated Certificate"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
(4)执行以下命令颁发证书
openssl ca -cert RootCA.pem -keyfile RootCA.key -in common.csr -out common.pem -days 3650 -md sha256 -extensions usr_cert
2.5.2 颁发多域名证书
(1)上传CSR文件到openssl指定的目录
同2.5.1
(2)选择直属上级CA的证书和key
同2.5.1
(3)在openssl.cnf文件里新增section [ v3_san ]
[ v3_san ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_san
[ alt_san ]
DNS.1 = san.crdc.cisco.com
IP.1 = x.x.x.x
(4)执行以下命令颁发证书
openssl ca -cert RootCA.pem -keyfile RootCA.key -in san.csr -out san.pem -days 3650 -md sha256 -extensions v3_san
2.5.3 颁发VPN Server的证书
(1)上传CSR文件到openssl指定的目录
同2.5.1
(2)选择直属上级CA的证书和key
同2.5.1
(3)在openssl.cnf文件里新增 section [ v3_vpn_server ]
[ v3_vpn_server ]
basicConstraints = critical, CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always, issuer:always
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment, keyAgreement
extendedKeyUsage = critical, serverAuth
subjectAltName = @alt_vpn_server
[ alt_vpn_server ]
DNS.1 = caowen-ipsecvpn.crdc.cisco.com
DNS.2 = caowen-sslvpn.crdc.cisco.com
DNS.3 = caowen-srst.crdc.cisco.com
DNS.4 = caowen-cme.crdc.cisco.com
IP.1 = 10.74.97.126
IP.2 = 100.101.0.254
IP.3 = 2001:10:74:97::126
IP.4 = 2001:100:101::254
(4)执行以下命令颁发证书
openssl ca -cert RootCA.pem -keyfile RootCA.key -in caowen-c2911.csr -out caowen-c2911.pem -days 3650 -md sha256 -extensions v3_vpn_server