我建议对外部和内部证书使用完全独立的根,以防止通过 Root01 泄露有关内部主机或用户的任何信息,同时也防止损坏软件的任何隐式信任。通过使用 2 个单独的根供外部和内部使用,无论软件有多损坏,任何信任都不可能从外部证书泄漏到内部证书。
通常,如果我们有如下所示的认证路径:
Root01 --> SubCA01 -> Cert01
Root01 --> SubCA02 -> Cert02
并且 SubCA02 被导入为受信任的。在有效的 PKI 实施中,不应信任 Cert01。但是正如您所知道的,通过惰性编码、损坏的软件和对证书的破解解析,信任有可能从 subCA02 泄漏到 Root01,从而导致 Cert01 被不应该信任该证书的人信任,如果PKI 实现非常糟糕,例如,自动假定任何更高的证书都是受信任的。是的,这有点牵强,但最好通过使用完全独立的根来解决任何损坏的软件。
除了名称约束之外,我还将添加一个 PathLength=0 基本约束,以防止 CA 证书被用于签署其他 CA 证书。
正如您可能知道的那样,那里有很多损坏的软件,并且可能发生特权升级攻击(当有人设法签署违反约束的证书时,您称之为),例如,如果所述 PolicyExt01 证书用于签署从属 CA,该 CA 又签署 S/MIME 证书。
一些损坏的软件仅检查例如命名约束“1 级深度”,添加路径长度约束会导致更长的链失败,而不是被接受为受信任。
所以我会这样做:
Root01 (Name constraints = Email=@domain.com, PathlenConstraint=0, EKU=Message signing)
Root02 (Internal applications, not trusted by 3rd parties...)
然后与应该信任它的第三方共享 Root01 证书,同时在所有公司内部计算机上安装 Root01 和 Root02。
Root01 和 Root02 都是自签名的根 CA 证书。
使用 Namingconstraint 时,我只会放置一个 Email=@domain.com 命名约束,然后将所有其他命名约束(IP、DNS、UPN、URI)作为通配符排除,以防止证书被用作例如网站SSL 证书,如果损坏的浏览器或 SSL 实现将无法解析密钥使用标志。
一个好主意也是测试您的设置,最好将根 CA 证书和私钥导出到安全的离线计算机,然后尝试用它签署“无效”证书。然后使用通用客户端软件测试“无效”证书,以确保约束生效并将证书标记为不受信任。
我个人不知道任何会导致这种“特权升级”攻击的显式配置,但如您所知,那里有很多损坏的 SSL 实现和 PKI 软件,所以最好安全而不是抱歉并尽可能限制证书,并且还使用单独的根来防止非常损坏的软件在证书之间发生任何信任泄漏。