X.509 证书中的 Name Constraints(名称约束)扩展是 PKI 安全的核心机制之一。它允许 CA 证书限制其下级证书的适用范围,防止被滥用来签发任意域名的证书。本文详细介绍其工作原理和实际使用方法。

什么是 Name Constraints

Name Constraints 是 X.509 证书标准(RFC 5280)定义的一个关键扩展,主要用于 CA 证书。它声明了该 CA 可以签发证书的域名和 IP 地址范围。

作用场景

  • 限制中间 CA 权限:企业私有 CA 可以限制下级 CA 只能签发特定域名的证书
  • 分层授权:在大型组织中实现细粒度的证书管理权限划分
  • 安全边界:防止某个被入侵的子 CA 被用来签发其他域名的证书

约束类型

Name Constraints 包含两种类型的约束:

类型 说明
permitted 允许使用的名称范围
excluded 禁止使用的名称范围

这两个可以同时使用,excluded 优先级更高。

证书格式

Name Constraints 扩展的 ASN.1 结构如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
NameConstraints ::= SEQUENCE {
     permittedSubtrees [0]     GeneralSubtrees OPTIONAL,
     excludedSubtrees [1]     GeneralSubtrees OPTIONAL
}

GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree

GeneralSubtree ::= SEQUENCE {
     base                    GeneralName,
     minimum         [0]     BaseDistance DEFAULT 0,
     maximum         [1]     BaseDistance OPTIONAL
}

支持的名称类型包括:

  • dNSName:域名(如 example.com
  • iPAddress:IP 地址(如 192.168.1.0/24
  • directoryName:目录名称(DN)
  • rfc822Name:电子邮件(较少使用)

实际操作

创建带 Name Constraints 的 CA 证书

使用 OpenSSL 创建根 CA 时添加名称约束:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 创建扩展配置文件
cat > ext_nc.cnf << 'EOF'
basicConstraints = critical, CA:TRUE
keyUsage = critical, keyCertSign, cRLSign
nameConstraints = permitted;DNS:.example.com, permitted;DNS:*.internal.example.com, excluded;DNS:evil.com
EOF

# 生成自签名 CA 证书
openssl req -x509 -new -nodes \
    -keyout root-ca.key \
    -out root-ca.crt \
    -days 3650 \
    -subj "/C=CN/O=Example CA/CN=Example Root CA" \
    -extfile ext_nc.cnf \
    -extensions v3_ca

查看证书中的 Name Constraints

1
2
# 查看证书扩展详情
openssl x509 -in root-ca.crt -noout -text | grep -A5 "Name Constraints"

输出示例:

1
2
3
4
5
6
X509v3 Name Constraints: 
    Permitted:
      DNS:.example.com
      DNS:*.internal.example.com
    Excluded:
      DNS:evil.com

验证下级证书是否符合约束

当使用这个受限 CA 签发证书时,只能签发符合约束的域名:

1
2
3
4
5
6
7
8
# 尝试为受限域名签发证书 - 成功
openssl req -new -keyout server.key -out server.csr \
    -subj "/C=CN/O=Example/CN=www.example.com"

openssl x509 -req -in server.csr \
    -CA root-ca.crt -CAkey root-ca.key \
    -out server.crt -days 365 \
    -CAcreateserial

如果尝试签发不符合约束的域名(如 www.evil.com),证书验证会失败:

1
2
3
4
5
# 尝试为被排除的域名签发证书 - 失败
openssl x509 -req -in <(openssl req -new -keyout test.key -out /dev/stdout \
    -subj "/C=CN/O=Test/CN=www.evil.com") \
    -CA root-ca.crt -CAkey root-ca.key \
    -out test.crt -days 365 2>&1

通常会报错:

1
2
Error opening CA certificate: ./root-ca.crt
3089079640:error:0B080074:x509 certificate routines:X509_check_ca:explicitly signs untrusted certificate:./root_ca.crt:verify error:num=0

IP 地址约束

Name Constraints 也支持 IP 地址范围:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 创建带 IP 约束的扩展配置
cat > ext_nc_ip.cnf << 'EOF'
basicConstraints = critical, CA:TRUE
keyUsage = critical, keyCertSign, cRLSign
nameConstraints = permitted;IP:10.0.0.0/255.0.0.0, permitted;IP:172.16.0.0/255.240.0.0, excluded;IP:10.100.0.0/255.255.0.0
EOF

openssl req -x509 -new -nodes \
    -keyout root-ca-ip.key \
    -out root-ca-ip.crt \
    -days 3650 \
    -subj "/C=CN/O=Example CA/CN=IP Restricted CA" \
    -extfile ext_nc_ip.cnf \
    -extensions v3_ca

查看 IP 约束:

1
openssl x509 -in root-ca-ip.crt -noout -text | grep -A3 "Name Constraints"
1
2
3
4
5
6
X509v3 Name Constraints: 
    Permitted:
      IP:10.0.0.0/255.0.0.0
      IP:172.16.0.0/255.255.240.0.0
    Excluded:
      IP:10.100.0.0/255.255.0.0

浏览器和应用程序支持

主流浏览器和应用程序都支持 Name Constraints:

应用 支持情况
Chrome/Edge 完全支持
Firefox 完全支持
OpenSSL 1.1.1+ 支持(通过 -name_constraints 验证)
Java (Java 11+) 支持
Go (crypto/x509) 支持

使用 OpenSSL 验证名称约束

1
2
3
# 创建一个测试场景:受限 CA + 不符合的下级证书
# 验证时会检查名称约束
openssl verify -CAfile root-ca.crt -name_constraints server.crt

安全最佳实践

1. 生产环境推荐配置

对于需要严格权限分离的 PKI 系统:

1
2
3
4
5
cat > production_nc.cnf << 'EOF'
basicConstraints = critical, CA:TRUE
keyUsage = critical, keyCertSign, cRLSign
nameConstraints = permitted;DNS:yourcompany.com, permitted;DNS:*.yourcompany.com
EOF

2. 避免过度宽松的约束

❌ 不推荐:允许所有域名

1
nameConstraints = permitted;DNS:.

✅ 推荐:明确指定允许的域名

1
nameConstraints = permitted;DNS:example.com, permitted;DNS:*.example.com

3. 结合其他安全措施

Name Constraints 应与其他 CA 安全措施配合使用:

  • 限制 CA 证书有效期
  • 配合路径长度约束(pathlen)
  • 使用专用的子 CA 处理不同业务线
1
2
3
4
5
6
7
8
# 完整的安全 CA 配置示例
cat > secure_ca.cnf << 'EOF'
basicConstraints = critical, CA:TRUE, pathlen:0
keyUsage = critical, keyCertSign, cRLSign
nameConstraints = permitted;DNS:internal.example.com, permitted;DNS:*.internal.example.com
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
EOF

总结

Name Constraints 是构建安全 PKI 系统的重要工具,它提供了:

  • 细粒度授权:限制子 CA 的签发范围
  • 防御深度:即使某个 CA 被入侵,损失也限于指定范围
  • 合规要求:满足某些行业标准的证书管理要求

在实际部署中,建议为每个子 CA 配置适当的名称约束,实现最小权限原则。


参考来源