OpenSSL 为证书添加 x509 v3 扩展

486 阅读3分钟

X.509v3 Extension 简介

之前的文章我介绍过 X.509 是一种标准规范,是 PKI 体系中的一员。是有 ITU(国际电信联盟)所制定的,类似的规范还有 X.208 和 X.680 等。X.509 规范在 1988 年开始发布,在 1996 年,更新了 V3 版本。目前普遍使用的就是版本就是 V3,通常表示成 X.509v3。

image.png

x.509v3 最大的特点就是添加了扩展字段(extension)

extension fields 主要有:

  • Basic Constraints
  • Key Usage
  • Extended Key Usage
  • Subject Alternative Name

其中 Subject Alternative Name 又简写成 SAN,是 v3 最突出的特征,常见形式如下:

subjectAltName=DNSName:*.google.ca,DNSName:*.google.ch,DNSName:*.google.fr
subjectAltName=email:copy,email:my@other.com,URI:http://my.url.here/
subjectAltName=IP:192.168.7.1,IP:13::17
subjectAltName=email:my@other.address,RID:1.2.3.4
subjectAltName=otherName:1.2.3.4;UTF8:some other identifier

OpenSSL 实战

添加 extensions

我们在使用 OpenSSL 制作证书的时候,通常有两个步骤:1)申请证书 2)签发证书

这两个步骤时我们都添加 extensions。

方法一:生成 CSR 时添加

CSR 是客户生成的证书请求文件,我们可以用 -config 选项指定 cnf 文件的方式添加 extensions,也可以用 -reqexts 选项指定 cnf 文件中的 section 的方式来添加 extensions。

(1) -config

我们可以在 openssl.cnf 中 添加这个 req_extensions 字段,如下:

image.png

执行:

openssl.cnf

openssl genrsa -out server.key 4096
openssl req -config /etc/ssl/openssl.cnf -new -sha256 -key vault.key -nodes -out vault.csr
(2) -reqexts

image.png

需要注意的是:req_ext.cnf 中,[ req_distinguished_name ] 必须提供,否则会报错。另外,我们必须同时提供 /etc/ssl/openssl.cnf 和 req_ext.cnf,而在 /etc/ssl/openssl.cnf 中的 [ req ] 段落中,指定了 distinguished_name  = req_distinguished_name,而 req_ext.cnf 中的值会覆盖 openssl.cnf 中的值。

image.png

完整命令:

req -key vault.key -new -sha256 -nodes -out vault.csr -subj="/CN=Vault Dev" \
  -reqexts reqexts -config <(cat /etc/ssl/openssl.cnf req_ext.cnf)
  
openssl req -new -sha256 \
    -key SERVER.key \
    -subj "/C=US/ST=North Carolina/O=ORG/OU=ORG_UNIT/CN=YOUR_DOMAIN_NAME" \
    -reqexts SAN \
    -config <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:YOUR_DOMAIN_NAME")) \
    -out SERVER.csr

注:

添加 -subj 的作用是免去 interactive 输入,如果没有这个,会进入交互模式填写 Country Name, Common Name, etc. 等信息的过程中。

检查 req ext

openssl req -noout -text -in vault.csr | rg "Requested Extensions" -A10

结果:

image.png

签发证书

现在有了 CSR,我们用 CA 对它签名即可颁发证书

openssl ca -in cert-request.csr -out user-certificate.crt

方法二:签发 cert 时添加

这种情况是,在生成 csr 时只添加 -subj,不添加 extensions,然后在生成 crt 时再添加 extensions,最终的效果都是一样的,crt 中有 extensions 信息,毕竟,csr 只是一个临时性的中间文件。

使用 -extensions 选项,并用 -extfile 来指定 extra cnf 文件。

openssl ca -policy policy_anything -config -out windows_server.crt \
  -extensions some_ext -extfile some_extensions.txt -infiles cert_request.csr
x509_ext.cnf

x509_ext.cnf

[ req ]
distinguished_name = req_distinguished_name
attributes = req_attributes
prompt = no

[ req_distinguished_name ]
CN = sf23607

[ req_attributes ]

[ cert_ext ]
subjectKeyIdentifier=hash
keyUsage=critical,digitalSignature,keyEncipherment
extendedKeyUsage=clientAuth,serverAuth

完整命令:

openssl genrsa -out server.key 4096
openssl req -config ./x509_ext.cnf -new -key server.key -nodes -out server.csr
openssl x509 -extfile ./x509_ext.cnf -extensions cert_ext -req -signkey server.key -in server.csr -out server.pem

最后,发布一个包含所有步骤的完整的命令:

openssl req -new -sha256 -key vault.key -nodes -out vault.csr \
  -config /etc/ssl/openssl.cnf 

openssl req -new -sha256 -nodes -key vault.key -out vault.csr \
    -subj="/O=HashiCorp/CN=vault-dev.slab" \
    -reqexts reqexts -config <(cat /etc/ssl/openssl.cnf req_ext.cnf)
    
openssl req -new -sha256 -passin file:icapass-pkcs8.enc \
    -key FactTrust_RSA_ICA1-PKCS8.key -out FactTrust_RSA_ICA1-PKCS8.csr \
    -subj="/C=US/O=Security/CN=FactTrust Secure RSA ICA1" \
    -reqexts req_ext -config <(cat /etc/ssl/openssl.cnf -<<END
[req_ext]
basicConstraints = critical,CA:true,pathlen:0
subjectKeyIdentifier = hash
keyUsage = critical,digitalSignature,keyCertSign,cRLSign
authorityInfoAccess = OCSP;URI:http://ocsp.facttrust.com/,caIssuers;URI:http://facttrust.com/certs/FactTrustRootCA.der
crlDistributionPoints = URI:http://crl.facttrust.com/FactTrustRootCA.crl
certificatePolicies = @pol

[pol]
policyIdentifier = 2.5.29.32.0
CPS.1 = "https://www.facttrust.com/CPS"
userNotice.1 = @notice

[notice]
explicitText = "UTF8:Notice An use of this Certificate constitutes acceptance of the Relying Party Agreement located at https://www.facttrust.com/rpa-ua"
END
)

全文完!

如果你喜欢我的文章,欢迎关注我的微信公众号 deliverit。