自签证书 首先约定好文件后缀
.key 私钥文件 Private Key
.csr 证书请求文件,csr = Certificate Signing Requests
.crt 证书文件 crt = Certificate
.crl 证书吊销列表 crl = Certificate Revocation List
.pem 包含私钥的证书,但是自动生成的不包含
自建CA 生成根
的私钥
1 openssl genrsa -des3 -out ca/root.key 2048
生成根
的证书请求文件,这时会提示交互输入一些信息
1 openssl req -new -key ca/root.key -out root.csr
也可以
1 openssl req -new -key ca/root.key -out ca/root.csr -subj "/C=CN/O=Test/OU=Test CA/CN=Test CA/emailAddress=ca@test.com"
自签名
1 openssl x509 -req -days 3650 -signkey ca /root.key -in ca /root.csr -out ca /root.crt
合成包含私钥的pem证书(文件)
1 cat ca /root.key ca /root.crt > ca /root.pem
这个ca/root.crt和ca/root.pem就是自签名CA,用它可以对其它证书进行签名
RootCA也可以添加扩展信息,比如 basicConstraints = CA:TRUE,下面会提到
用自建CA进行签名 生成server1
的key
1 openssl genrsa -des3 -out keys/server1.key 2048
生成server1
的证书请求文件
1 openssl req -new -key keys/server1.key -out csrs/server1.csr -subj "/C=CN/O=Test/OU=dev/CN=server1.test.com/emailAddress=ops@test.com"
用CA给server.csr签名
1 openssl ca -in csrs/server1.csr -out certs/server1.crt -config openssl.cnf
查验server1.crt证书
1 2 openssl x 509 -in certs/server1 .crt -noout -text | less openssl x 509 -in certs/server1 .crt -noout -serial -subject
openssl.cnf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 [ ca ] default_ca = TEST_CA[ TEST_CA ] dir = .private_key = $dir /ca/root.keycertificate = $dir /ca/root.crtnew_certs_dir = $dir /newcertscerts = $dir /certsdatabase = $dir /index.txtserial = $dir /serialdefault_md = sha256default_days = 365 policy = policy_match[ policy_match ] countryName = matchstateOrProvinceName = optionalorganizationName = matchorganizationalUnitName = optionalcommonName = suppliedemailAddress = supplied
目录结构tree
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 . |-- ca | |-- root.crt | |-- root.csr | |-- root.key | `-- root.pem |-- certs | `-- server1.crt |-- csrs | `-- server1.csr |-- index.txt |-- index.txt.attr |-- index.txt.old |-- keys | `-- server1.key |-- newcerts | `-- 01.pem |-- openssl.cnf |-- serial `-- serial.old 5 directories, 14 files
配置文件中提到的文件或目录都是手工创建,其中还需要
配置文件中未提到的文件系自动生成
index.txt.attr 签发证书时的属性, unique_subject = yes; 当然也可以写到配置文件中
index.txt.old 最近一次的index.txt
serial.old 最近一次签发证书的serial number
中间过程可能遇到的问题 error while loading serial number
serial需初始化一个值
failed to update database TXT_DB error number 2
1 2 index .txt.attrunique_subject = no
证书吊销 openssl.conf增加一些配置(同步创建crls目录及echo ‘01’ > crls/crlnumber)
1 2 3 crlnumber = $dir /crls/crlnumbercrl = $dir /crls/certificate.crldefault_crl_days = 30
吊销证书
1 openssl ca -revoke certs/server1.crt -config openssl.cnf
生成吊销证书列表
1 openssl ca -gencrl -out crls/certificate.crl -config openssl.cnf
查看吊销列表
1 openssl crl -in crls/certificate.crl -noout -text | less
CA发布CRL一般都会有周期性,所以客户端不能基于CRL实时检查某证书是否过期
现在一般通过OCSP(Online Certificate Status Protocol),在线证书状态协议
证书扩展 生成待签名的server2.csr
1 2 openssl genrsa -des3 -out keys /server2.key 2048 openssl req -new -key keys /server2.key -out csrs/server2.csr -subj "/C=CN/O=Test/OU=dev/CN=server2.test.com/emailAddress=ops@test.com"
增加openssl.cnf相关配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 diff --git a/openssl.cnf b/openssl.cnf index 2 bb77dd..d99eb1e 100644 --- a/openssl.cnf +++ b/openssl.cnf @@ -14 ,7 +14 ,8 @@ default_days = 365 crlnumber = $dir/crls/crlnumber crl = $dir/crls/crl.pem default_crl_days = 30 -policy = policy_match+x509_extensions = usr_cert +policy = policy_match - [ policy_match ] countryName = match @@ -24 ,6 +25 ,13 @@ organizationalUnitName = optional commonName = supplied emailAddress = supplied - +[ usr_cert ] +basicConstraints = CA:FALSE + +nsCertType = client, email +keyUsage = digitalSignature, keyEncipherment +nsComment = "Certificate Generated by Test CA" +
如果想给一个Web站点签发,可按需添加
1 2 3 extendedKeyUsage = serverAuth, clientAuthsubjectAltName = DNS:\*.test.com DNS:test.com
用CA对server2.csr签名
1 openssl ca -in csrs/server2.csr -out certs/server2.crt -config openssl.cnf
可以对比查看server2.crt和server1.crt的区别
1 openssl x509 -in certs/server2.crt -noout -text | less
二级CA 实际生产环境中,很少直接用RootCA直接签发业务证书,一般是二级或多级CA去签发
新创建一工作目录,并复用RootCA的目录结构和配置文件
1 2 mkdir /root/second_ca_test cd /root/second_ca_test
生成二级CA的key及其证书请求文件
1 2 openssl genrsa -des3 -out ca/second .key 2048 openssl req -new -key ca/second .key -out ca/second .csr -subj "/C=CN/O=Test/OU=Test SecondCA/CN=Test SecondCA/emailAddress=ca@test.com"
使用RootCA签发二级CA前,RootCA的openssl.cnf配置文件需要更改
usr_cert 只保留以下配置即可
1 2 [ usr_cert ] basicConstraints = CA:FALSE
签发二级CA: 遇到路径问题自行修改,因为’dir = .’没有使用绝对路径
1 openssl ca -in ca /second.csr -out ca /second.crt -config ../openssl/openssl.cnf
二级CA签发的证书一般需要合并,RootCA一般需导入或已内置(浏览器、系统)
1 2 3 4 5 6 7 8 9 --- - - --- - - --- - - - --- - - - --- - - --- - - --- - - - --- - - - --- - - --- - - --- - - - --- - - -
证书校验
1 openssl verify -verbose -CAfile ...
建议
提前规划,比如多少级CA,分别做什么
私钥一定要加密保存,养成良好习惯
根据实际情况,脚本化签发证书
按需对证书有效期进行监控并预警
配置文件示例 openssl.cnf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 [ ca ] default_ca = TEST_CA[ TEST_CA ] dir = .private_key = $dir /ca/root.keycertificate = $dir /ca/root.crtnew_certs_dir = $dir /newcertscerts = $dir /certsdatabase = $dir /index.txtserial = $dir /serialdefault_md = sha256default_days = 365 crlnumber = $dir /crls/crlnumbercrl = $dir /crls/crl.pemdefault_crl_days = 30 x509_extensions = usr_certpolicy = policy_match[ policy_match ] countryName = matchstateOrProvinceName = optionalorganizationName = matchorganizationalUnitName = optionalcommonName = suppliedemailAddress = supplied[ usr_cert ] basicConstraints = CA:FALSE nsCertType = client, emailkeyUsage = digitalSignature, keyEnciphermentextendedKeyUsage = serverAuth, clientAuthsubjectAltName = DNS:\*.test.com DNS:test.comnsComment = "Certificate Generated by Test CA" [ req ] distinguished_name = req_distinguished_name[ req_distinguished_name ] countryName = Country Name (2 letter code)countryName_default = CNcountryName_min = 2 countryName_max = 2 stateOrProvinceName = State or Province Name (full name)stateOrProvinceName_default =localityName = Locality Name (eg, city)localityName_default =0.organizationName = Organization Name (eg, company)0.organizationName_default = TestorganizationalUnitName = Organizational Unit Name (eg, section)organizationalUnitName_default = DevcommonName = Common Name (e.g. server FQDN or YOUR name)emailAddress = Email AddresscommonName_max = 64
其它 去除key的密码
1 openssl rsa -in keys /server1.key -out keys /server1_nopass.key
生成公钥
1 openssl rsa -in keys /server1_nopass.key -pubout > server1.pub
更多 man x509
man x509v3_config
或’https://www.openssl.org/docs/manmaster/man5/x509v3_config.html'
man req
…