CA:FALSE 表示该证书不能用作中间证书了,也就是说不能拿这个证书继续去签发新的证书。
window上执行生成证书
MSYS_NO_PATHCONV=1 ./openssl_gen_certs.sh
注:在windows上,使用gitbash来生成证书,需要补充MSYS_NO_PATHCONV=1
在命令的前面,不然会报错。
生成证书
1、生成 ca 证书:
# 生成CA证书私钥文件(ca_private.key):
openssl genrsa -out ca_private.key 2048
# 生成CA证书签名请求CSR文件(ca.csr):
openssl req -new -key ca_private.key -out ca.csr
# 生成 X.509 格式的CA证书 ca.crt:
openssl x509 -req -days 365 -in ca.csr -signkey ca_private.key -out ca.crt
2、使用 ca 证书签发服务端 server.crt 和客户端证书 client.crt:
# 生成服务端证书私钥文件server_private.key:
openssl genrsa -out server_private.key 2048
# 生成服务端证书签名请求CSR文件(server.csr):
openssl req -new -key server_private.key -out server.csr
# 服务端用 server.csr 文件向CA机构申请签名证书,签名过程需要CA的公钥证书和私钥参与,最终生成一个带有CA签名的服务器端证书
openssl x509 -req -days 365 -CA ca.crt -CAkey ca_private.key -CAcreateserial -in server.csr -out server.crt
注:生成私钥文件时,如果想加密的话,就需要用下面的写法,执行的时候就会提示你输入密码:
openssl genrsa -aes256 -out server.key 2048
打开私钥文件后,可以看到内容里面有提示加密的算法:
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,BD067F720F2FE645F757923E8064423E
FCL/l0OFBAkd8iIKUSfbF18zpnSccZyHDBLfTRdvl1YJEEyBK9eN8z935n46TDE1
Generating RSA private key, 2048 bit long modulus (2 primes)
使用脚本获取目标网站的证书
#!/bin/bash
#服务端地址
host=$1
#端口
port=$2
#证书名称
certName=$3
#获取证书
echo "Q" | openssl s_client -connect ${host}:${port} -servername ${host} -showcerts | openssl x509 -outform pem > ${certName}.crt
使用方法:
> vim get_certs_by_domain_port.sh
> chmod a+x get_certs_by_domain_port.sh
> sh ./get_certs_by_domain_port.sh ip port server
举例:
sh ./get_certs_by_domain_port.sh 51.32.17.130 7443 server
检查服务端证书和CA证书的DN字段是否不一致
参见:https://www.rfc-editor.org/rfc/rfc5280.txt
Where it is non-empty, the subject field MUST containan X.500 distinguished name(DN). The DN MUST be unique for each subject entity certified by the one CA as defined by the issuer field. ACA MAY issue more than one certificate with the same DN to the same subject entity.
无论您使用什么方法来生成证书和密钥文件,服务器和客户端证书/密钥使用的通用名称值必须与CA证书使用的通用名称值各不相同。否则,证书和密钥文件将不能用于使用OpenSSL编译的服务器。
下面描述来自于华为的安全排查清单项:
证书的主体通用名称 Common Name 域相当于用户名的概念,代表设备(或设备的某个模块)的身份,因此不同设备(或设备不同的模块)向CA申请证书时,除了生成的公私钥对不同外,Common Name的取值也应不同。建议在证书主体通用名称中含有产品唯一性信息(如电子序列号ESN、IP地址、MAC地址、服务器名称等),用来和其他设备(或设备的其他模块)做区分。
SAN 设置
说明:SAN(Subject Alternative Name)是 SSL 标准 x509 中定义的一个扩展。使用了 SAN 字段的 SSL 证书,可以扩展此证书支持的域名,使得一个证书可以支持多个不同域名的解析。
1、生成带SAN的证书:https://www.cnblogs.com/Principles/p/CloudComputing007.html
2、krm registry 的证书,配置了 san 信息,值为主备节点的IP地址以及浮动IP的信息,举例如下:
> openssl x509 -noout -text -in server.crt
...
X509v3 extensions:
X509v3 Subject Alternative Name:
IP Address:110.2.8.103, IP Address:110.2.8.104, IP Address:110.2.8.105
...
3、给证书添加SAN字段:
[xxx.cnf]
1、给证书添加某一个ip,或者某几个ip:
subjectAltName=IP.1:51.32.18.120
subjectAltName=IP.1:51.32.18.120,IP.2:51.32.18.121,IP.3:51.32.18.122
2、给证书添加某一个域名,或者某几个域名,或者某个正则匹配:
subjectAltName=DNS.1:krm.huawei.com
subjectAltName=DNS.1:krm.huawei.com,DNS.2:krm2.huawei.com
subjectAltName=DNS.1:*.huawei.com
注:只有同时配有IP和域名,才能在IP和域名访问时都成功识别。
更新证书信任链
1、将 CA 根证书拷贝到服务器上的证书信任域里面:/etc/pki/ca-trust/source/anchors
cp ca.crt /etc/pki/ca-trust/source/anchors // 拷贝ca证书
2、更新证书链:
update-ca-trust // 更新证书链
openssl 使用
1、查看版本:
[root@localhost shenjl]# openssl
OpenSSL> version
OpenSSL 1.1.1 FIPS 11 Sep 2018
[root@HN01 ~]# openssl
OpenSSL> version
OpenSSL 1.1.1f 31 Mar 2020
2、查看证书信息:
openssl x509 -noout -text -in server.crt
3、验证证书(ca根证书验证服务端证书):
openssl verify -CAfile ca.crt server.crt
举例:
VRM01:/etc/galax/certs/registry # openssl verify -CAfile rootCA.crt server.crt
server.crt: OK
说明:因为server.crt证书是由rootCA.crt签发的,所以能够验证成功
4、验证私钥:
openssl rsa -in server.key
// 输入密码
// 即可查看私钥文件
RM01:/opt/galax/registry/certs # openssl rsa -in server.key
Enter pass phrase for server.key:
writing RSA key
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA3nGbjs18IF0Rm9TAZ7KcKrQgIGm8E0mp62xZ+67+64qpNfgY
7Xg7Vb4HS5K35Ga3hy0pkXeaEzMEQM/EEVm2JPXO664dq3EFxQyTV++lYYgBuHS3
DlpgDplPSW2P4tEq1deG1X4tQrKMrIZkvxMWWZLkF68mEkEqUCtOWcD8+FBoghHy
/NUFd/vn6YL/1VuE4e+yfiwYelLYo10FReJLjIqCaFH+7tyxvCJAJShDcDQWuHPq
VusVMeYMqeqwI7TymI+dyAyRcXynSzzZbeRi/hrZJ0bGfkfZax75exzplvVtAHdO
VR6hjQk7qUNwbWEuEzLQ3m0wiIT0T8Nthu0WGQIDAQABAoIBAQCvH0uzSiy9oee6
Ae2T9faiW/qq6fMqUCUY9c2FqoiA0UJT/cVKNwynfRprMc/aXc+A+VovbrR7BwAD
Mk6Oxkzynh5QR1yOW0WKk1LwuPc/aH7KRADVqOrUs3fLPBk6HSgXAD3jmBlz1/ON
46QvFYzT6iPuTXKwjmMMiHt/h8LgjZz9qWb690h8Fjsyj2Gm6DeemiHZwUfmsg2J
16mdDP5vtmutWkoAWbbkIxp9/P6F/M3x88fu2Nh4F7xwYfud91VQAzvir0HvkWcd
VJe2GZkV9TzjT0UGLQaMUejzCnQms4m8gADvB69ketocsUNRIJLFxPdANwyKOGMq
W3dgI3u9AoGBAPpTS9zULt2G2wMtjQL3OwsBj09ttlJOtd7DFQQjXpz/47x4jtj8
XiS8amOd5t6wdrDFJRSGDfNcONxsgsN+V9SceFlBjFAf9YHJlC/8iMlhJPYcvuSC
8bZyMiJrXbRcIVgPwEON5dt6A2hMnb9QvXDMD5p7CtLUfdfXo7U9PPCPAoGBAON8
gdHsYfcAq4XHIHlTeOLpe4U3ZN8Ink9DS99P68lHmE2JXMqHgZODrh+YcMAp8Fr/
A5YZa46KlHES91zgGIt1W4vioSiANMN/uafTqbEQfhjIpfWDjOP8j1C1UUo7ZAJd
CR8n5JOA7bqED7BlPC8MZuj6wUPfBX3k1khjWxLXAoGAco68IQtZhze38vRdnAXY
l2jXVNo4neI3iQJuE768Bc11Q0NI3DRiQR2Y8o3IohDPwIX4OjQ/HigOPZHLJfwj
5cDVssM0m1aE3CiMEInZb49tgtQU6C6kv4HzP50y/N9MwygyLLg7gP2NoaWua2df
yscYPPIiOenUzXp6CO9FfDECgYAEUzOsqA/cwFiCfJyzcdDUj5fXmowCaYmI/ECP
CFf1RbUxlDD9cMIX6eL/mshZ/vIg6MRKsEUJOr1DwRaO33vX+u04paBmwrk+FkmT
VUTepu+ezQHKvyuIkh6vbCMVhDeMi/RGcV25KDRc3XHm6qXQRy4Vs97EyZKzKAyi
57CtlQKBgQC8jhq6Oom9lr+yThpjEpscsxmKOC75Ok7tBgBoz6QdQi9R2UgJPFZl
8vZny9WMlBqazYJstrkMttgwEivMuOP1YxgBu5pblf3pa6EFr+yU+Ur0nZt8xIM4
Kah4x6OvBaoyM8Cj9Bv3aJTz37L2m84qqzK4uM3uEG/kYap6PBE52w==
-----END RSA PRIVATE KEY-----
VRM01:/opt/galax/registry/certs
su registry -s /bin/bash -c "${cmd}"
常见错误及处理
Q: javax.net.ssl.SSLException: Certificate doesn't match any of the subject alternative names
A:如果证书不正常,比如 SAN 信息没有,就会出现 javax.net.ssl.SSLException: Certificate doesn't match any of the subject alternative names 的错误,原因是系统的httpClient在build的时候启用了 setSSLHostnameVerifier,会校验服务端证书中的host信息是否与请求地址的host信息一致,不一致则会报错。这里的host支持域名和ip两种。启用的目的是加强一层安全防护,防止恶意程序利用中间人攻击。