xiaoming728

xiaoming728

OpenSSL创建自签名证书

2023-12-12
OpenSSL创建自签名证书

来源:Ryan4Yin'sSpace

链接:https://ryan4yin.space/posts/about-tls-cert/

日期:2021-01-17

基于 RSA 算法的 TLS 证书

到目前为止 RSA 仍然是应用最广泛的非对称加密方案,几乎所有的根证书都是使用的 2048 位或者 4096 位的 RSA 密钥对。

对于 RSA 算法而言,越长的密钥能提供越高的安全性,当前使用最多的 RSA 密钥长度仍然是 2048 位,但是 2048 位已被一些人认为不够安全了,密码学家更建议使用 3072 位或者 4096 位的密钥。

生成一个 2048 位的 RSA 证书链的流程如下:

OpenSSL 的 CSR 配置文件官方文档: https://www.openssl.org/docs/manmaster/man1/openssl-req.html

  1. 编写证书签名请求的配置文件 csr.conf

[ req ]
prompt = no
default_md = sha256  # 在签名算法中使用 SHA-256 计算哈希值
req_extensions = req_ext
distinguished_name = dn

[ dn ]
C = CN  #国家
ST = ZJ 
L = hz
O = linewell
OU = archives
CN = 192.168.206.181 # 泛域名,这个字段已经被 chrome/apple 弃用了。

[ alt_names ] # 备用名称,chrome/apple 目前只信任这里面的域名。
IP = 192.168.206.181 # IP地址

[ req_ext ]
subjectAltName = @alt_names

[ v3_ext ]
subjectAltName=@alt_names  # Chrome 要求必须要有 subjectAltName(SAN)
authorityKeyIdentifier=keyid,issuer:always
basicConstraints=CA:FALSE
keyUsage=keyEncipherment,dataEncipherment,digitalSignature
extendedKeyUsage=serverAuth,clientAuth

此文件的详细文档: OpenSSL file formats and conventions

  1. 生成证书链与服务端证书:

# 1. 生成本地 CA 根证书的私钥
openssl genrsa -out ca.key 2048
# 2. 使用私钥签发出 CA 根证书
openssl req -x509 -new -nodes -key ca.key -subj "/CN=MyLocalRootCA" -days 398 -out ca.crt
# 3. 生成服务端证书的 RSA 私钥(2048 位)
openssl genrsa -out server.key 2048
# 4. 通过第一步编写的配置文件,生成证书签名请求(公钥+申请者信息)
openssl req -new -key server.key -out server.csr -config csr.conf
# 5. 使用 CA 根证书直接签发服务端证书,这里指定服务端证书的有效期为 398 天
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
  -CAcreateserial -out server.crt -days 398 \
  -extensions v3_ext -extfile csr.conf

简单起见这里没有生成中间证书,直接使用根证书签发了用于安全通信的服务端证书。

基于 ECC 算法的 TLS 证书

ECC(Elliptic Curve Cryptography) 算法被认为是比 RSA 更优秀的算法。与 RSA 算法相比,ECC 算法使用更小的密钥大小,但可提供同样的安全性,这使计算更快,降低了能耗,并节省了内存和带宽。

对于 RSA 密钥,可以提供不同的密钥大小(密钥大小越大,加密效果越好)。
而对于 ECC 密钥,您应选择要用哪种曲线生成密钥对。各个组织(ANSI X9.62、NIST、SECG)命名了多种曲线,可通过如下命名查看 openssl 支持的所有椭圆曲线名称:

openssl ecparam -list_curves

目前在 TLS 协议以及 JWT 签名算法中,目前应该最广泛的椭圆曲线仍然是 NIST 系列:

  • P-256: 在 openssl 中对应的名称为 prime256v1;到目前为止P-256是应用最为广泛的椭圆曲线

  • P-384:在 openssl 中对应的名称为 secp384r1

  • P-521:在 openssl 中对应的名称为 secp521r1

生成一个使用 P-384 曲线的 ECC 证书的示例如下:

  1. 编写证书签名请求的配置文件 ecc-csr.conf:

[ req ]
prompt = no
default_md = sha256 # 在签名算法中使用 SHA-256 计算哈希值
req_extensions = req_ext
distinguished_name = dn

[ dn ]
C = CN  #国家
ST = ZJ 
L = hz
O = linewell
OU = archives
CN = 192.168.206.181 # 泛域名,这个字段已经被 chrome/apple 弃用了。

[ alt_names ] # 备用名称,chrome/apple 目前只信任这里面的域名。
IP = 192.168.206.181 # IP地址

[ req_ext ]
subjectAltName = @alt_names

[ v3_ext ]
subjectAltName=@alt_names  # Chrome 要求必须要有 subjectAltName(SAN)
authorityKeyIdentifier=keyid,issuer:always
basicConstraints=CA:FALSE
keyUsage=keyEncipherment,dataEncipherment,digitalSignature
extendedKeyUsage=serverAuth,clientAuth

此文件的详细文档: OpenSSL file formats and conventions

  1. 生成证书链与服务端证书

# 1. 生成本地 CA 根证书的私钥,使用 P-384 曲线,密钥长度 384 位
openssl ecparam -genkey -name secp384r1 -out ecc-ca.key
# 2. 使用私钥签发出 CA 根证书
openssl req -x509 -new -nodes -key ecc-ca.key -subj "/CN=MyLocalRootCA" -days 398 -out ecc-ca.crt
# 3. 生成服务端证书的 EC 私钥,使用 P-384 曲线,密钥长度 384 位
openssl ecparam -genkey -name secp384r1 -out ecc-server.key
# 4. 通过第一步编写的配置文件,生成证书签名请求(公钥+申请者信息)
openssl req -new -key ecc-server.key -out ecc-server.csr -config ecc-csr.conf
# 5. 使用 CA 根证书直接签发 ECC 服务端证书,这里指定服务端证书的有效期为 398 天
openssl x509 -req -in ecc-server.csr -CA ecc-ca.crt -CAkey ecc-ca.key \
  -CAcreateserial -out ecc-server.crt -days 398 \
  -extensions v3_ext -extfile ecc-csr.conf

查看证书详情

# 查看KEY信息
cat ca.key
cat server.key
# 查看CSR信息
openssl req -noout -text -in server.csr
# 查看证书信息
openssl x509 -noout -text -in server.crt

关于证书寿命

对于公开服务,服务端证书的有效期不要超过 825 天(27 个月)!而 2020 年 11 月起,新申请的服务端证书有效期缩短到了 398 天(13 个月)。目前 Apple/Mozilla/Chrome 都发表了相应声明,证书有效期超过上述限制的,将被浏览器/Apple设备禁止使用。

对于其他用途的证书,如果更换起来很麻烦,可以考虑放宽条件。
比如 kubernetes 集群的加密证书,可以考虑有效期设长一些,比如 10 年。

云原生安全破局|如何管理周期越来越短的数字证书?所述,大量知名企业如 特斯拉/微软/领英/爱立信 都曾因未及时更换 TLS 证书导致服务暂时不可用。

因此 TLS 证书最好是设置自动轮转!人工维护不可靠!