是否可以创建一个 CA 证书(即使是未签名的),它只允许为特定的受限域签署证书,这样它就不会被滥用于其他域?
我可以限制证书颁发机构仅签署某些域吗?
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 Constraints
SSL 的现有实现大多不支持该扩展。他们可能会忽略扩展名。当 SSL 客户端连接到服务器时,它会在服务器证书中查找服务器名称,如RFC 2818,第 3.1 节中所述。它将
dNSName
在Subject Alt Name
扩展中查找类型名称,并且这些名称(理论上)由Name Constraints
. 但是,如果服务器证书缺少Subject Alt Name
扩展名,客户端将使用公用名(在 中subjectDN
)。公用名不在Name Constraints
. 这意味着证书可以通过省略Subject Alt Name
扩展名并将任意服务器名称放入其公用名中来规避名称限制。
(这就是 X.509 的全部内容:许多有用的功能的钩子和规定,由于缺乏实施支持和规范机构之间缺乏协调,这些功能不起作用。)