
工作以后,旅行除了缓解工作 PTSD 症状,还有了另一层意义:检验自己作为一个社会人的社会功能是否还正常,避免和社会生活脱节。
- 🎯 打造私有 CA,Part 1:手搓根 CA
- 打造私有 CA,Part 2:手搓子 CA、签发服务证书
随着国内对安全越来越重视(整活越来越多),即使是企业内网的在线服务,也对 HTTPS 有了强烈的需求。HTTPS 的两个主要任务是验证通信端身份、提供安全传输通道,其中身份的验证依赖于 PKI 体系(背景知识请参考前面一篇博文 Web 安全,Part 1:PKI 扫盲),简单来说,就是依赖于证书,公认的权威可信机构颁发的证书就是互联网世界的合法身份,但这个证书通常需要 💰。
除了找权威机构申请正式证书,如果不需要在互联网上公开受信,也可以自己生成,自己生成的证书在操作系统和浏览器中没有信任锚点,没有权威第三方背书,默认情况下是不受信任的。
对于内网,企业能去购买有公信力的证书固然好(人傻钱多?🤔),但对于自己能控制的环境,如果执着于使用公网受信的证书,也有点杀鸡用牛刀。企业的内网环境,主要还是开发、测试、辅助办公应用,随着这几年 RESTful 风格接口的流行,采用 http 协议的场景也越来越多,有了 http,那下一步走向 https 也就是顺理成章的事 —— 早做准备不吃亏。
如果选择自己提供证书,有两种选择:
- 自签名证书(使用自己的私钥签名的证书)
- 使用私有 CA 签名证书(使用 CA 的私钥签名的证书,当然私有根 CA 的证书一定是自签名证书)
对于企业来说,如果选择一事一议,每次生成一个自签名证书,因为系统的建设、管理、维保、运维的方式各异,建设、管理、维保、运维的人员也各不相同,这样的作法会导致混乱,难以进行有效管理,并且存在填补微观层面安全漏洞的同时又引入一个体系层面的漏洞,很难说哪个风险更大。
更好的做法是搭建一套私有 CA,私有 CA 的好处有以下几点:
- 在各种操作系统/浏览器环境中一次性下好信任锚(CA 根证书),以后私有 CA 签出的任何证书都不必再在客户端重新执行受信操作;
- 信任完全受企业自己控制;
- 让零散的工作进入企业的工作视野,避免推诿或遗漏;
- 便于对证书进行统一管理(如签发/吊销证书),消灭漏网之鱼,消除混乱;
- 便于对证书操作动作进行标准化和自动化,降低操作风险和相关人员心智负担;
- 更好地顺应企业、行业,甚至国家的发展趋势。
下面我们就使用 OpenSSL 来搭建一套 mini Private CA,我的本地环境是 Fedora Workstation 36。
1、准备相关路径
mkdir root-ca
cd root-ca
mkdir certs db private
chmod 700 private
touch db/index
echo 1001 > db/serial
echo 1001 > db/crlnumber
touch root-ca.conf
2、根 CA 配置文件 root-ca.conf
# 定义一些接下来的配置里用到的变量
[default]
name = root-ca
domain_suffix = example.com
aia_url = http://$name.$domain_suffix/$name.crt
crl_url = http://$name.$domain_suffix/$name.crl
ocsp_url = http://ocsp.$name.$domain_suffix:9080
default_ca = ca_default
name_opt = utf8,esc_ctrl,multiline,lname,align
# CA 的 DN 名
[ca_dn]
countryName = "GB"
organizationName = "Example"
commonName = "Root CA"
# CA 的关键配置项
[ca_default]
home = .
database = $home/db/index
serial = $home/db/serial
crlnumber = $home/db/crlnumber
certificate = $home/$name.crt
private_key = $home/private/$name.key
RANDFILE = $home/private/random
new_certs_dir = $home/certs
unique_subject = no
copy_extensions = none
default_days = 3650
default_crl_days = 365
default_md = sha256
policy = policy_c_o_match
# 字段要求
[policy_c_o_match]
countryName = match
stateOrProvinceName = optional
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
# 生成 CA 自己的自签名证书请求的配置项
[req]
default_bits = 4096
encrypt_key = yes
default_md = sha256
utf8 = yes
string_mask = utf8only
prompt = no
distinguished_name = ca_dn
req_extensions = ca_ext
[ca_ext]
basicConstraints = critical,CA:true
keyUsage = critical,keyCertSign,cRLSign
subjectKeyIdentifier = hash
# 用于签发子 CA 证书
[sub_ca_ext]
authorityInfoAccess = @issuer_info
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:true,pathlen:0
crlDistributionPoints = @crl_info
extendedKeyUsage = clientAuth,serverAuth
keyUsage = critical,keyCertSign,cRLSign
nameConstraints = @name_constraints
subjectKeyIdentifier = hash
[crl_info]
URI.0 = $crl_url
[issuer_info]
caIssuers;URI.0 = $aia_url
OCSP;URI.0 = $ocsp_url
# 限制 CA 可用于的域名
[name_constraints]
permitted;DNS.0=example.com
permitted;DNS.1=example.org
excluded;IP.0=0.0.0.0/0.0.0.0
excluded;IP.1=0:0:0:0:0:0:0:0/0:0:0:0:0:0:0:0
# OCSP 证书的一些关键配置
[ocsp_ext]
authorityKeyIdentifier = keyid:always
basicConstraints = critical,CA:false
extendedKeyUsage = OCSPSigning
keyUsage = critical,digitalSignature
subjectKeyIdentifier = hash
3、生成根 CA 私钥和证书请求
openssl req -new \
-config root-ca.conf \
-out root-ca.csr \
-keyout private/root-ca.key
4、生成自签名根 CA 证书
openssl ca -selfsign \
-config root-ca.conf \
-in root-ca.csr \
-out root-ca.crt \
-extensions ca_ext
5、生成 CRL
CRL(Certificate Revocation List)就是证书吊销列表。
openssl ca -gencrl \
-config root-ca.conf \
-out root-ca.crl
试试吊销 1002 证书
openssl ca \
-config root-ca.conf \
-revoke certs/1002.pem \
-crl_reason keyCompromise
6、签发 OCSP 服务证书
生成 OCSP(Online Certificate Status Protocol)服务的私钥和证书请求
openssl req -new \
-newkey rsa:2048 \
-subj "/C=GB/O=Example/CN=OCSP Root Responder" \
-keyout private/root-ocsp.key \
-out root-ocsp.csr
使用根 CA 证书签发 OCSP 证书
openssl ca \
-config root-ca.conf \
-in root-ocsp.csr \
-out root-ocsp.crt \
-extensions ocsp_ext \
-days 365
7、验证 OCSP 功能
用 openssl 直接起一个 OCSP 监听服务
openssl ocsp \
-port 9080 \
-index db/index \
-rsigner root-ocsp.crt \
-rkey private/root-ocsp.key \
-CA root-ca.crt \
-text
发起一个证书验证请求,验证 root-ocsp.crt 证书状态
openssl ocsp \
-issuer root-ca.crt \
-cert root-ocsp.crt \
-VAfile root-ocsp.crt \
-url http://127.0.0.1:9080

现在有了根 CA,下一篇就基于根 CA 创建子 CA,并使用子 CA 来签发实际的服务证书,如网站证书。
Reference:
0 条评论