本文介绍基于OpenSSL
自建CA
证书、二级CA
证书和SSL
证书,以及如何使用 openssl
查看证书。
基础知识
创建CA
签发一级CA证书
方法一:直接通过命令行签名
生成根密钥
openssl genrsa -out cakey.key 4096
为了安全起见,修改cakey.key
私钥文件权限为600
或400
,也可以使用子shell生成( umask 077; openssl genrsa -out cakey.key 4096
),下面不再重复。
示例:
# openssl genrsa -out cakey.key 4096
Generating RSA private key, 4096 bit long modulus
.......................++
.........................................................................................................................................................................................................................................................................................................................++
e is 65537 (0x10001)
生成根证书
使用req命令生成自签证书:
openssl req -new -x509 -days 14610 -key cakey.key -out cacert.crt
# openssl req -new -x509 -days 14610 -key cakey.key -out cacert.crt
...
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Henan
Locality Name (eg, city) [Default City]:Zhengzhou
Organization Name (eg, company) [Default Company Ltd]:X Technology Co. Ltd.
Organizational Unit Name (eg, section) []:X Root CA Trust
Common Name (eg, your name or your server's hostname) []:X Root CA - R3
Email Address []:me@xiexianbin.cn
查看证书
openssl x509 -in cacert.crt -noout -text
生成SSL密钥
以上都是在CA服务器上做的操作,而且只需进行一次,现在转到nginx服务器上执行:
cd /etc/nginx/ssl
openssl genrsa -out all.xiexianbin.cn.key 2048
这里测试的时候CA中心与要申请证书的服务器是同一个。
生成证书签署请求
# openssl req -new -days 3650 -key all.xiexianbin.cn.key -out all.xiexianbin.cn.csr
...
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:ShangHai
Locality Name (eg, city) [Default City]:ShangHai
Organization Name (eg, company) [Default Company Ltd]:xiexianbin.cn
Organizational Unit Name (eg, section) []:IT
Common Name (eg, your name or your server's hostname) []:*.xiexianbin.cn
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
同样会提示输入一些内容,其它随便,除了Commone Name
一定要是你要授予证书的服务器域名或主机名,challenge password
不填。
私有CA签署证书
接下来要把上一步生成的证书请求csr文件,发到CA服务器上,在CA上执行:
openssl ca -in all.xiexianbin.cn.csr -out all.xiexianbin.cn.crt
# 上面的命令生成的证书不能识别,试试下面的命令
openssl x509 -req -days 825 -in all.xiexianbin.cn.csr -CA /etc/pki/CA/cacert.crt -CAkey /etc/pki/CA/private/cakey.key -CAcreateserial -out all.xiexianbin.cn.crt
示例:
创建ext:all.xiexianbin.cn.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage=digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment
subjectAltName=@alt_names
extendedKeyUsage=serverAuth
# crlDistributionPoints=URI:https://ca.xiexianbin.cn/crl.crl
[alt_names]
DNS.1 = xiexianbin.cn
DNS.2 = *.xiexianbin.cn
DNS.3 = kb.cx
DNS.4 = *.kb.cx
DNS.4 = localhost
# openssl x509 -req -days 825 -in all.xiexianbin.cn.csr -CA cacert.crt -CAkey cakey.key -CAcreateserial -out all.xiexianbin.cn.crt -extfile all.xiexianbin.cn.ext -sha256
Signature ok
subject=/C=CN/ST=Shanghai/L=Shanghai/O=xiexianbin.cn/OU=IT/CN=*.xiexianbin.cn/emailAddress=me@xiexianbin.cn
Getting CA Private Key
说明:
- -days 必须少于 825 天,否则报错
NET::ERR_CERT_REVOKED
上面签发过程其实默认使用了-cert cacert.crt -keyfile cakey.key
,这两个文件就是前两步生成的位于/etc/pki/CA
下的根密钥和根证书。将生成的crt
证书发回nginx
服务器使用。
到此我们已经拥有了建立ssl
安全连接所需要的所有文件,并且服务器的crt
和key
都位于配置的目录下。
验证生成的SSL证书
校验证书是否被 CA 证书签名:
# openssl verify -CAfile cacert.crt all.xiexianbin.cn.crt
all.xiexianbin.cn.crt: OK
生成bundle.crt
cat all.xiexianbin.cn.crt cacert.crt > all.xiexianbin.cn.bundle.crt
方法二:通过配置文件签名
上述方法是通过命令行,过程过于繁琐,可以使用配置文件进行签名
pki目录结构
CentOS
上有关ssl
证书的目录结构:
/etc/pki/CA/
newcerts 存放CA签署(颁发)过的数字证书(证书备份目录)
private 用于存放CA的私钥
crl 吊销的证书
/etc/pki/tls/
cert.pem 软链接到certs/ca-bundle.crt
certs/ 该服务器上的证书存放目录,可以房子自己的证书和内置证书
ca-bundle.crt 内置信任的证书
private 证书密钥存放目录
openssl.cnf openssl的CA主配置文件
修改CA的一些配置文件
CA要给别人颁发证书,首先自己得有一个作为根证书,我们得在一切工作之前修改好CA的配置文件、序列号、索引等等。
vi /etc/pki/tls/openssl.cnf:
...
[ CA_default ]
dir = /etc/pki/CA # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
#unique_subject = no # Set to 'no' to allow creation of
# several ctificates with same subject.
new_certs_dir = $dir/newcerts # default place for new certs.
certificate = $dir/cacert.crt # The CA certificate
serial = $dir/serial # The current serial number
crlnumber = $dir/crlnumber # the current crl number
# must be commented out to leave a V1 CRL
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.key # The private key
RANDFILE = $dir/private/.rand # private random number file
...
default_days = 3650 # how long to certify for
...
# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
...
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = CN
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Henan
...
[ req_distinguished_name ] 部分主要是颁证时一些默认的值,可以不动
一定要注意[ policy_match ]中的设定的匹配规则,是有可能因为证书使用的工具不一样,导致即使设置了csr中看起来有相同的countryName,stateOrProvinceName等,但在最终生成证书时依然报错:
Using configuration from /usr/lib/ssl/openssl.cnf
Check that the request matches the signature
Signature ok
The stateOrProvinceName field needed to be the same in the
CA certificate (GuangDong) and the request (GuangDong)
touch index.txt serial
在CA目录下创建两个初始文件:
# touch index.txt serial
# echo 01 > serial
签名:
openssl ca -config /etc/pki/tls/openssl.cnf -out all.xiexianbin.cn.crt -in all.xiexianbin.cn.csr -extfile all.xiexianbin.cn.cnf -batch
签发中级CA证书
生成二级CA密钥
# openssl genrsa -out secondcakey.key 4096
Generating RSA private key, 4096 bit long modulus
......................++
.......................................................................................................................................................................++
e is 65537 (0x10001)
生成二级CA证书签名请求(CSR)
使用req命令生成自签证书:
# openssl req -new -key secondcakey.key -out secondcsr.csr
...
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Henan
Locality Name (eg, city) [Default City]:Zhengzhou
Organization Name (eg, company) [Default Company Ltd]:X Technology Co. Ltd. ## 务必确保Organization Name与根CA证书相同
Organizational Unit Name (eg, section) []:X Authority
Common Name (eg, your name or your server's hostname) []:X Authority - R3
Email Address []:me@xiexianbin.cn
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
生成二级CA证书
创建ext:secondcert.ext
basicConstraints=CA:true
crlDistributionPoints=URI:https://ca.xiexianbin.cn/crl.pem
# openssl x509 -req -days 7305 -CA cacert.crt -CAkey cakey.key -CAcreateserial -in secondcsr.csr -out secondcacert.crt -extfile secondcert.ext -sha256
Signature ok
subject=/C=CN/ST=Henan/L=Zhengzhou/O=X Technology Co. Ltd./OU=X Root CA Trust/CN=X Authority - R3/emailAddress=me@xiexianbin.cn
Getting CA Private Key
同样会提示输入一些内容,其它随便,除了Commone Name
一定要是你要授予证书的服务器域名或主机名,challenge password
不填。
验证二级CA证书
# openssl verify -CAfile cacert.crt secondcacert.crt
secondcacert.crt: OK
生成证书链文件
cat secondcacert.crt cacert.crt > secondcacert.chain.crt
使用二级CA证书签名
# openssl x509 -req -days 825 -in all.xiexianbin.cn.csr -CA secondcacert.crt -CAkey secondcakey.key -CAcreateserial -out all.xiexianbin.cn.crt -extfile all.xiexianbin.cn.ext -sha256
Signature ok
subject=/C=CN/ST=Shanghai/L=Shanghai/O=xiexianbin.cn/OU=IT/CN=*.xiexianbin.cn/emailAddress=me@xiexianbin.cn
Getting CA Private Key
验证生成的SSL证书
校验证书是否被 CA 证书签名:
# openssl verify -CAfile secondcacert.chain.crt all.xiexianbin.cn.crt
all.xiexianbin.cn.crt: OK
生成bundle.crt
cat all.xiexianbin.cn.crt secondcacert.crt > all.xiexianbin.cn.bundle.crt
使用SSL证书
nginx配置
在nginx配置文件(可能是/etc/nginx/nginx.conf
)的server指令下添加:
ssl_certificate /etc/nginx/conf.d/cert/all.xiexianbin.cn.bundle.crt;
ssl_certificate_key /etc/nginx/conf.d/cert/all.xiexianbin.cn.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl on;
同时注意 server_name
与证书申请时的 Common Name
要相同,打开443端口。当然关于web服务器加密还有其他配置内容,如只对部分URL加密,对URL重定向实现强制https访问,请参考其他资料。
访问域名问题
浏览器作为客户端去访问https加密的服务器,一般不用去手动做其他设置,如https://www.xiexianbin.cn
,这是因为Chrome、FireFox、Safari、IE
等浏览器已经内置了大部分常用的CA的根证书,但自建CA的根证书就不再浏览器的信任列表中,访问时会提示红色错误。
如果你要自己做CA,别忘了客户端需要导入CA的证书(CA的证书是自签名的,导入它意味着你“信任”这个CA签署的证书)。而商业CA的一般不用,因为它们已经内置在你的浏览器中了。
导出导入自签名证书
如何信任自签 CA 证书
其他工具
cfssl
是 CloudFlare
公司开发的一款开源的工具包,被用来捆绑TLS/SSL证书链,并作为内部证书颁发机构基础架构- go-ca SSL自签名客户端,自动生成Root CA、二级CA、域名证书。基于 x-ca 格式开发。