本文使用openssl工具生成RSA算法的三级CA证书,组成证书链,并使用证书链签名客户端证书和服务端证书。

可以通过证书链对生成的客户端和服务端证书进行校验。

RootCA

openssl genrsa -out root.key 2048
openssl req -sha512 -new -x509 -key root.key -out root.crt -days 3650
# 将crt证书转为pem
openssl x509 -in root.crt -out root.pem
# 查看证书信息
openssl x509 -text -noout -in root.crt
# 将pem格式证书转换为pfx格式
openssl pkcs12 -export -out root.pfx -inkey root.key -in root.pem

2级CA

openssl genrsa -out secondca.key 2048
openssl req -new -days 3650 -key secondca.key -out secondca.csr
openssl ca -extensions v3_ca -in secondca.csr  -days 3650 -out secondca.crt -cert ../root/root.crt -keyfile ../root/root.key
openssl x509 -in secondca.crt -out secondca.pem
openssl pkcs12 -export -out secondca.pfx -inkey secondca.key -in secondca.pem

3级CA

openssl genrsa -out thirdca.key 2048
openssl req -new -days 3650 -key thirdca.key -out thirdca.csr
openssl ca -extensions v3_ca -in thirdca.csr -days 3650 -out thirdca.crt -cert ../secondca/secondca.crt -keyfile ../secondca/secondca.key
openssl x509 -in thirdca.crt -out thirdca.pem
openssl pkcs12 -export -out thirdca.pfx -inkey thirdca.key -in thirdca.pem

Server证书

openssl genrsa -out server.key 2048
openssl req -key server.key -new -out server.csr -config openssl.conf
openssl ca -in server.csr  -days 3650 -out server.crt -cert ../thirdca/thirdca.crt -keyfile ../thirdca/thirdca.key
openssl x509 -text -noout -in server.crt
openssl x509 -in server.crt -out server.pem
openssl pkcs12 -export -out server.pfx -inkey server.key -in server.pem

openssl.conf的内容如下

[ req ]
default_bits       = 2048
distinguished_name = req_distinguished_name
req_extensions     = req_ext

[ req_distinguished_name ]
countryName                 = Country Name (2 letter code)
countryName_default         = CN
stateOrProvinceName         = State or Province Name (full name)
stateOrProvinceName_default = SH
localityName                = Locality Name (eg, city)
localityName_default        = XA
organizationName            = Organization Name (eg, company)
organizationName_default    = Personal
organizationalUnitName            = Organizational Unit Name (eg, section)
organizationalUnitName_default    = None
# CN定义的是将要申请SSL证书的域名或子域名或主机名。
# 例如要为zhonghua.com申请ssl证书则填写zhonghua.com,而不能填写www.zhonghua.com
# 要为www.zhonghua.com申请SSL则填写www.zhonghua.com
# 基于本地搭建的测试服务,则使用localhost或者127.0.0.1
# CN必须和将要访问的网站地址一样,否则访问时就会给出警告
# 该项要填写正确,否则该请求被签名后证书中的CN与实际环境中的CN不对应,将无法提供证书服务
commonName                  = Common Name (e.g. server FQDN or YOUR name)
commonName_max              = 64
commonName_default          = localhost

[ req_ext ]
subjectAltName = @alt_names

[alt_names]
IP.1    = 127.0.0.1
DNS.1   = localhost

Client证书

openssl genrsa -out client.key 2048
openssl req -key client.key -new -out client.csr
openssl ca -in client.csr  -days 3650 -out client.crt -cert ../thirdca/thirdca.crt -keyfile ../thirdca/thirdca.key
# 生成不同格式的证书文件
openssl x509 -text -noout -in client.crt
openssl x509 -in client.crt -out client.pem

校验

# 将多个证书文件打包为证书链
cat ../thirdca/thirdca.crt ../secondca/secondca.crt ../root/root.crt > full.crt
cat ../thirdca/thirdca.pem ../secondca/secondca.pem ../root/root.pem > full.pem
# 验证server证书
openssl verify -verbose -CAfile full.pem server.pem
openssl verify -verbose -CAfile full.crt server.crt
# 验证client证书
openssl verify -verbose -CAfile full.pem client.pem
openssl verify -verbose -CAfile full.crt client.crt