我可以限制证书颁发机构仅签署某些域吗?

信息安全 tls 证书 公钥基础设施 证书颁发机构
2021-08-25 12:38:06

是否可以创建一个 CA 证书(即使是未签名的),它只允许为特定的受限域签署证书,这样它就不会被滥用于其他域?

2个回答

Thomas Pornin回答很好,但有点过时了。支持Name Constraints越来越多。

我发现 OpenSSL 1.0.1k 和 Windows 7 支持该扩展。

测试

使用XCA,我创建了一个自签名 CA 证书,并通过在证书创建期间在“高级”选项卡上添加以下行来添加一个关键Name Constraints扩展.lab.example.com

nameConstraints=critical,permitted;DNS:.lab.example.com

注意:约束不应前导点。这在技术上是不正确的,但对此的支持正在扩大:https ://github.com/golang/go/commit/e4dafa32620e80e4e39937d8e2033fb2ee6085f8

然后,我使用该 CA 证书为 HTTPS 服务器签署了另外两个证书:

  • test.lab.example.com - 有效的
  • bad.google.com - 明显无效

接下来,在相应地设置 DNS 条目后,我使用此修改simple-https-server.py来运行 HTTPS 服务器,每个生成的证书一次:

./simple-https-server --certfile test.lab.example.com.pem --hostname test.lab.example.com

./simple-https-server --certfile bad.google.com.pem --hostname bad.google.com

将 CA 证书安装到操作系统信任后,我尝试使用多个客户端访问每个站点。

结果

OpenSSL 1.0.1k 似乎支持这一点。curl当我尝试访问时给了我以下错误bad.google.com

curl: (60) 不允许此证书的认证机构颁发具有此名称的证书。

Windows 7 上的 Chrome 也做了正确的事情。Chrome 提供了一个相当通用的net::ERR_CERT_INVALID,但 Windows 证书查看器非常明确:

证书的名称无效。该名称未包含在允许列表中或被明确排除。

参考


更新 1

我还尝试签署一个没有指定主题备用名称的证书,而是仅依赖旧的通用名称。

OpenSSL / curl 仍然拒绝接受证书。

Windows 上的 Chrome 和 IE11 都拒绝接受 Windows 上的证书,即使 Windows 本身(查看服务器证书时)没有抱怨它。对我来说,这意味着浏览器所做的不仅仅是要求操作系统验证证书,这是一件好事。


请注意,早于 2018 年初发布的 10.13.3 版本的 OSX 不正确支持名称约束。


结论

我觉得要求其他人安装我的根 CA 证书是安全的,而不会给他们带来任何风险。

不。

(我假设您正在谈论 SSL 服务器的证书。)

技术上没有。与此最接近的是Name Constraints扩展(参见RFC 5280 的第 4.2.1.10 节)(OID 2.5.29.30),理论上允许将完整的 PKI 子树限制为一组明确的域(及其子域)。该扩展支持白名单和黑名单语义(在您的情况下,您需要一个白名单)。然而,在实践中,这失败了有两个原因:

  • Name ConstraintsSSL 的现有实现大多不支持扩展。他们可能会忽略扩展名。

  • 当 SSL 客户端连接到服务器时,它会在服务器证书中查找服务器名称,如RFC 2818,第 3.1 节中所述。它将dNSNameSubject Alt Name扩展中查找类型名称,并且这些名称(理论上)由Name Constraints. 但是,如果服务器证书缺少Subject Alt Name扩展名,客户端将使用公用名(在 中subjectDN)。公用名不在Name Constraints. 这意味着证书可以通过省略Subject Alt Name扩展名并将任意服务器名称放入其公用名中来规避名称限制。

(这就是 X.509 的全部内容:许多有用的功能的钩子和规定,由于缺乏实施支持和规范机构之间缺乏协调,这些功能不起作用。)