X.509v3 Extension 简介
之前的文章我介绍过 X.509 是一种标准规范,是 PKI 体系中的一员。是有 ITU(国际电信联盟)所制定的,类似的规范还有 X.208 和 X.680 等。X.509 规范在 1988 年开始发布,在 1996 年,更新了 V3 版本。目前普遍使用的就是版本就是 V3,通常表示成 X.509v3。
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 字段,如下:
执行:
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
需要注意的是: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 中的值。
完整命令:
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
结果:
签发证书
现在有了 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。