OpenSSL 证书扩展字段全解与实战示例
本文档旨在提供一份最全、最易懂的 X.509 v3 证书扩展字段说明。我们将晦涩的专业术语翻译成大白话,并为每一个扩展字段都提供了命令行 (-addext) 和 配置文件 (openssl.cnf) 两种实战写法。
目录
- 基础限制类 (Basic Constraints, Key Usage...)
- 身份标识类 (SAN, SKI, AKI...)
- 信息与管理类 (CRL, AIA, Policies...)
- 高级与特殊类 (Name Constraints, TLS Feature...)
- 完整的配置文件模板
1. 基础限制类
这些字段决定了证书“能干什么”以及“能不能传给别人”。
1.1 Basic Constraints (基本约束)
- 一句话解释:标记这张证书是“大老板” (CA) 还是“普通员工” (终端实体)。
- 通俗理解:如果是 CA,它就能给别人发证;如果是普通员工,只能自己用。
- 关键参数:
CA:TRUE(老板) 或FALSE(员工)。pathlen: (可选) 只有老板才有。限制下面能有几层“小老板”。0表示只能直管员工,不能有下级经理。
实战示例
场景 A:普通服务器证书 (员工)
- 命令行:
-addext "basicConstraints = critical, CA:FALSE" - 配置文件:
basicConstraints = critical, CA:FALSE
场景 B:根证书 (大老板)
- 命令行:
-addext "basicConstraints = critical, CA:TRUE" - 配置文件:
basicConstraints = critical, CA:TRUE
1.2 Key Usage (密钥用法)
- 一句话解释:限制这把钥匙具体能开哪扇门。
- 通俗理解:这把钥匙是用来签合同的(签名),还是用来加密保险箱的(加密),还是用来发证的(签发证书)。
- 关键参数:
digitalSignature: 数字签名 (验证身份)。keyEncipherment: 密钥加密 (HTTPS 握手用)。keyCertSign: 签发证书 (CA 必备)。cRLSign: 签发吊销列表 (CA 必备)。
实战示例
场景 A:HTTPS 网站证书
- 命令行:
-addext "keyUsage = critical, digitalSignature, keyEncipherment" - 配置文件:
keyUsage = critical, digitalSignature, keyEncipherment
场景 B:CA 根证书
- 命令行:
-addext "keyUsage = critical, keyCertSign, cRLSign" - 配置文件:
keyUsage = critical, keyCertSign, cRLSign
1.3 Extended Key Usage (增强密钥用法 - EKU)
- 一句话解释:指定证书的具体应用场景。
- 通俗理解:这虽然是张身份证,但我想明确它只能用于“开服务器”或者“写代码”。
- 关键参数:
serverAuth: 网站服务器 (HTTPS)。clientAuth: 客户端身份验证 (双向认证)。codeSigning: 代码签名。emailProtection: 邮件加密。
实战示例
场景:既做服务器又做客户端
- 命令行:
-addext "extendedKeyUsage = serverAuth, clientAuth" - 配置文件:
extendedKeyUsage = serverAuth, clientAuth
2. 身份标识类
这些字段告诉别人“我是谁”,“我的备用名是什么”,“我的上级是谁”。
2.1 Subject Alternative Name (SAN - 主体备用名称)
- 一句话解释:最重要字段。列出证书适用的所有域名、IP 或邮箱。
- 通俗理解:证书的“真名”是 CN,但浏览器现在只看 SAN。这里可以写“大名”、“小名”、“英文名”和“家庭住址”。
- 关键参数:
DNS,IP,email,URI。
实战示例
场景:多域名和 IP
- 命令行:
-addext "subjectAltName = DNS:example.com, DNS:*.example.com, IP:192.168.1.1" - 配置文件:
subjectAltName = @alt_names [ alt_names ] DNS.1 = example.com DNS.2 = *.example.com IP.1 = 192.168.1.1
2.2 Subject Key Identifier (SKI - 主体密钥标识符)
- 一句话解释:给你的公钥打个指纹。
- 通俗理解:为了防止同名同姓搞混,给这把钥匙算一个唯一的 ID。
- 关键参数:
hash(自动计算,推荐)。
实战示例
- 命令行:
-addext "subjectKeyIdentifier = hash" - 配置文件:
subjectKeyIdentifier = hash
2.3 Authority Key Identifier (AKI - 授权密钥标识符)
- 一句话解释:指明是谁(哪把钥匙)签发了这张证书。
- 通俗理解:这上面写着“我爸是李刚(的ID)”,方便浏览器顺藤摸瓜找到上级证书。
- 关键参数:
keyid:always(总是包含密钥ID),issuer(包含颁发者名称,可选)。
实战示例
- 命令行:
-addext "authorityKeyIdentifier = keyid:always, issuer" - 配置文件:
authorityKeyIdentifier = keyid:always, issuer
2.4 Issuer Alternative Name (IAN - 颁发者备用名称)
- 一句话解释:颁发者(CA)的备用联系方式。
- 通俗理解:如果你找不到发证机构的正式地址,可以试试这些备用地址。
- 现状:极少使用,通常直接看颁发者信息就够了。
实战示例
- 命令行:
-addext "issuerAltName = DNS:ca.example.org" - 配置文件:
issuerAltName = issuer_alt_section [ issuer_alt_section ] DNS.1 = ca.example.org
3. 信息与管理类
这些字段告诉别人“去哪查我的状态”或者“我有什么政策”。
3.1 CRL Distribution Points (CRL 分发点)
- 一句话解释:去哪里下载“黑名单”(证书吊销列表)。
- 通俗理解:如果我犯事了被吊销了,你可以去这个网址查到我的名字。
- 关键参数:
URI。
实战示例
- 命令行:
-addext "crlDistributionPoints = URI:http://crl.example.com/ca.crl" - 配置文件:
crlDistributionPoints = crl_section [ crl_section ] fullname = URI:http://crl.example.com/ca.crl
3.2 Authority Info Access (AIA - 授权信息访问)
- 一句话解释:去哪里在线验证证书状态 (OCSP),或者去哪里下载上级证书。
- 通俗理解:
- OCSP: “打电话问问警察局(CA),这人现在是不是好人”。
- caIssuers: “如果你没见过我爸(上级CA),去这下载他的照片(证书)”。
实战示例
- 命令行:
-addext "authorityInfoAccess = OCSP;URI:http://ocsp.example.com, caIssuers;URI:http://crt.example.com/ca.crt" - 配置文件:
authorityInfoAccess = @aia_section [ aia_section ] OCSP;URI.0 = http://ocsp.example.com caIssuers;URI.0 = http://crt.example.com/ca.crt
3.3 Certificate Policies (证书策略)
- 一句话解释:证书的使用条款和法律声明。
- 通俗理解:就像软件的“用户协议”,通常给一个链接 (CPS) 让你去读。
实战示例
- 命令行: 较复杂,建议用配置文件。
- 配置文件:
certificatePolicies = @pol_section [ pol_section ] policyIdentifier = 1.3.6.1.4.1.12345.1.1 CPS.1 = "http://cps.example.com/legal.html"
4. 高级与特殊类
这些字段通常用于非常具体的场景。
4.1 Name Constraints (名称约束)
- 一句话解释:CA 专用。限制这个 CA 只能签发特定后缀的域名。
- 通俗理解:给了你盖章的权力,但规定你“只能批
.com的地皮,不能批.cn的”。 - 关键参数:
permitted(允许),excluded(禁止)。
实战示例
场景:只允许签发 example.com 下的证书
- 命令行:
-addext "nameConstraints = permitted;DNS:example.com" - 配置文件:
nameConstraints = @name_constraints [ name_constraints ] permitted;DNS.0 = example.com excluded;IP.0 = 0.0.0.0/0.0.0.0 # 禁止签发任何 IP 证书
4.2 TLS Feature (TLS 功能扩展)
- 一句话解释:强制浏览器检查特定 TLS 功能。最常用的是 OCSP Must Staple。
- 通俗理解:强制要求:“我不光要出示身份证,我还得同时出示今天的‘无犯罪记录证明’(OCSP Stapling),否则别信我”。
- 关键参数:
status_request(即 OCSP Must Staple)。
实战示例
- 命令行:
-addext "tlsfeature = status_request" - 配置文件:
tlsfeature = status_request
4.3 Netscape Comment (NS 注释)
- 一句话解释:已过时。以前 Netscape 浏览器用的,现在仅用于给人看个备注。
- 通俗理解:在证书里写一句“到此一游”。
实战示例
- 命令行:
-addext "nsComment = This is a generated cert" - 配置文件:
nsComment = "This is a generated cert"
5. 完整的配置文件模板
复制以下内容保存为 my_cert.cnf,根据需要修改 [ v3_req ] 下的内容。
# =============================================================
# OpenSSL 证书生成配置文件模板
# =============================================================
[ req ]
default_bits = 2048
distinguished_name = req_distinguished_name
req_extensions = v3_req # 生成 CSR 时读取此段
x509_extensions = v3_req # 生成自签名证书时读取此段
string_mask = utf8only
prompt = no # 不交互,直接读取下方 DN
[ req_distinguished_name ]
C = CN
ST = Beijing
L = Beijing
O = MyCompany
OU = Tech Dept
CN = my.example.com
[ v3_req ]
# -------------------------------------------------------------
# 1. 基础限制
# -------------------------------------------------------------
basicConstraints = critical, CA:FALSE
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
# -------------------------------------------------------------
# 2. 身份标识 (最重要的部分)
# -------------------------------------------------------------
subjectAltName = @alt_names
subjectKeyIdentifier = hash
# -------------------------------------------------------------
# 3. 信息与管理 (可选)
# -------------------------------------------------------------
# authorityKeyIdentifier = keyid:always, issuer
# crlDistributionPoints = URI:http://crl.example.com/ca.crl
# authorityInfoAccess = OCSP;URI:http://ocsp.example.com
[ alt_names ]
DNS.1 = my.example.com
DNS.2 = www.example.com
DNS.3 = localhost
IP.1 = 127.0.0.1
IP.2 = 192.168.0.100