用openssl添加https访问并设置客户端信任
前置知识:
x.509 是密码学里面的公钥证书的格式标准. 就是说x.509是一种证书的格式,其实我们经常用这种格式的证书,只是可能没怎么注意过证书格式的标准而已.
pkcs 是公钥密码学标准. 其包含了一系列的标准,其中包括证书申请、证书更新、证书作废表发布、扩展证书内容以及数字签名、数字信封的格式等方面的一系列相关协议 (引用自百度百科)
- 数字证书一般是第三方机构签发的,这时候我们需要向第三方机构提供“证书请求文件”(通常为csr后缀的文件), 证书请求文件的特征是:
以“-----BEGIN CERTIFICATE REQUEST-----” 开头,以 “-----END CERTIFICATE REQUEST-----” 结尾.
在linux中,我们可以通过如下openssl 命令生成证书请求文件:
~]# openssl genrsa -out private.key # 首先生成私钥 private.key
~]# openssl req -new -key private.key -out request.csr -days 365 #根据证书签发机构提供的信息,按照提示生成csr 文件.其中的 C, ST, O 必须和证书签发机构提供的信息相一致,否则无法签发成功.
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:
...... #忽略后面一长串的内容
- 用linux的openssl 命令来生成证书的命令只需要比上面生成 csr 文件命令多一个 “-x509 ” 参数.
首先看下 openssl req 命令的-x509 option的意义, 在如下的结果中,我们可以看到-x509指出 其输出 一个x509结构的文件来代替 req 文件. 所以没有 -x509选项,那么默认生成的是csr 的证书请求文件,而加上 x509就表示生成一个x509结构的证书文件.
OpenSSL> req help
unknown option help
req [options] <infile >outfile
where options are
...... #忽略了一大段,我们只关注x509 参数的意义.
-x509 output a x509 structure instead of a cert. req.
...... #忽略了一大段,我们只关注x509 参数的意义.
证书有两种,一种是通过对CSR进行签发生成的,还有一种就是无需签发的证书。这种无需签发的证书通常也叫做CA证书. 无论是签发的还是CA证书,都是X.509格式的证书. X.509格式的证书的特点是:
以 “-----BEGIN CERTIFICATE-----” 开头,以“-----END CERTIFICATE-----” 结尾.
- 对于X509格式的证书(无论是CA证书还是签发生成的证书),如何查看这个证书的subject 信息呢?
~]# openssl x509 -in ./myca.pem -subject #其中 myca.pem 是需要查看subject信息的证书.
...... #这里省略输出的结果.
除了X509格式的证书,我们也可以查看证书请求文件的subject 信息:
~]# openssl req -in my_request.csr -noout -text -subject #其中my_request.csr 就是证书请求文件
Certificate Request:
Data:
Version: 0 (0x0)
Subject: C=CN, ST=HB, L=NONE, O=ITCOMPANY, OU=ST, CN=*.my.com
...... #省略了大部份的输出结果
#################################################################################
#################################################################################
上面介绍了如何创建CSR ,CA以及查看CSR 以及CA中的subject 信息,有了上面的基础,我们来生成自己小站需要的https证书,然后在server end 和client end 进行配置:
- 生成我们自己的CA证书.
#忽略生成私钥my.key的过程.
~]# openssl req -x509 -new -key my.key -out mycert.pem -days 365
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:HB
Locality Name (eg, city) [Default City]:HD
Organization Name (eg, company) [Default Company Ltd]:ITCOMPANY
Organizational Unit Name (eg, section) []:TECH
Common Name (eg, your name or your server's hostname) []:COMPUTER
Email Address []:xxx@xxx.com
- 查看我们自签CA证书的subject 信息:
~]# openssl x509 -in ./mycert.pem -subject
subject= /C=CN/ST=HB/L=HD/O=ITCOMPANY/OU=TECH/CN=COMPUTER emailAddress=xxx@xxx.com #此为证书的subject信息
-----BEGIN CERTIFICATE-----
......
- 生成证书请求文件,证书请求文件生成过程中要求的 Country Name(C), State or Province Name (ST) 以及Organization Name(O) 必须和CA 的相同,否则在后面进行签名的时候会报错.
而Common Name 通常是证书需要绑定的URL. 至于L ,OU 如果没有明确指定,那么就随意了.
#忽略了生成私钥my_csr_key.key的过程.
~]# openssl req -new -key my_csr_key.key -out my_request.csr -days 365
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:HB
Locality Name (eg, city) [Default City]:Town
Organization Name (eg, company) [Default Company Ltd]:ITCOMPANY
Organizational Unit Name (eg, section) []:develop
Common Name (eg, your name or your server's hostname) []:*.my.com
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
- 查看生成的证书请求文件my_request.csr:
~]# openssl req -in my_request.csr -noout -text -subject
Certificate Request:
Data:
Version: 0 (0x0)
Subject: C=CN, ST=HB, L=Town, O=ITCOMPANY, OU=develop, CN=*.my.com
...... #省略大部分内容
- 用openssl 命令实现对CSR的签名, 生成签名证书. 在执行签名命令之前,需要注意:
A. /etc/pki/CA/index 这个文件用于跟踪已经签发的证书,如果没有签发过,那么该文件应该为0字节.
B. /etc/pki/CA/serial 这个文件里面里面保存的是最后一次签发的证书的序列号,初始值应该为01,也可以为00等其他的值.
如果以上两个文件缺失或者内容不符合规范,会导致签发命令执行时报错.
~]# openssl ca -in ./my_request.csr -out ./my.crt -days 365 -cert ./mycert.pem -keyfile ./my.key
Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 1 (0x1)
Validity
Not Before: Jul 4 12:11:59 2020 GMT
Not After : Jul 4 12:11:59 2021 GMT
Subject:
countryName = CN
stateOrProvinceName = HB
organizationName = ITCOMPANY
organizationalUnitName = develop
commonName = *.my.com
X509v3 extensions:
X509v3 Basic Constraints:
...... #忽略后面的内容,签发成功后的证书文件为 my.crt.
上面用CA证书对CSR进行签发,签发完成后,我们就获得了CSR对应的证书my.crt.
那么作为同样是x509格式的my.crt , 是否可以像CA一样对CSR进行签发呢?
经个人验证,这个确实可以.
- 查看生成的证书文件my.crt 的subject, 因为生成的my.crt 也是x.509格式的数字证书,所以用该openssl x509命令
~]# openssl x509 -in ./my.crt -subject
subject= /C=CN/ST=HB/O=ITCOMPANY/OU=develop/CN=*.my.com
-----BEGIN CERTIFICATE-----
MIIDwjCCAqqgAwIBAgIBATANBgkqhkiG9w0BAQsFADB5MQswCQYDVQQGEwJDTjEL
......
-----END CERTIFICATE-----
- 上面生成的my.crt 就是要用于https的证书文件,而my_csr_key.key就是该证书对应的私钥.
CA证书是:mycert.pem
httpd 的conf.d/ssl.conf 中需要指定如下的配置项:
SSLCertificateFile /etc/httpd/conf.d/my.crt #指定证书路径
SSLCertificateKeyFile /etc/httpd/conf.d/my_csr_key.key #指定私钥的路径
SSLCACertificateFile /etc/httpd/conf.d/mycert.pem #指定根证书的路径.
在上述的配置中需要注意的是:
SSLCertificateFile 指定的是用于https的证书,SSLCertificateKeyFile指定的是相应的私钥
而SSLCACertificateFile通常是指定CA证书的路径,但是也可以是my.crt的签发者(不一定是CA),正如上面所述,openssl需要的证书并不一定需要CA来签发. 配置完成,重启httpd服务就可以了。
- 在客户端,只需要信任server.crt 的签发者 mycert.pem 就可以了。不同类型的客户端配置信任的方式不同,比如浏览器,通常会提示是不可信的证书,根据提示一步步信任就可以了(在实际的上网中,不要随便信任提示不安全的证书哦,以防掉入钓鱼网站的陷阱).
而在linux系统中,比如curl 命令则使用的是 os层面信任的证书。这时候需要在os层面信任该证书:
下面演示的是在linux (centos 7)os 中信任这个根证书的方式:
~]# cp mycert.pem /etc/pki/ca-trust/source/anchors
~]# update-ca-trust
在这里有几点需要说明的是:
A. pkcs 是公钥密码学标准,在os 里面一般都有一个 /etc/pki/ 这个目录,个人猜测是 pki 是pkcs interface的缩写。所以关于证书相关的配置基本都在这个目录下。
B. 更新信任证书 的命令在不同的系统中可能不同,请查看相应命令的man 帮助文档来找到存放 待信任证书的正确位置(centos/rhel 是 update-ca-trust), 然后运行更新证书的命令.
C. 更新完成之后,这个证书在/etc/pki/ca-trust/extracted 下面对应的每种证书里面都是可信任的,比如这个证书会出现在 java/cacerts 里面,也就是java 的keystore 里面,查看这个文件中包含的证书,需要用keytool命令, 也会出现在 pem 目录下的其他证书里面, 还有openssl 目录下面的证书列表里...也就是说,这是一个全局状态的更新