我需要一些帮助来确保我们的PKI基础结构安全.它是这样工作的:
>我们有一个(自签名)CA证书,表明我们的服务器拥有完全控制权.
>所有客户端(用Java编写)都配置有仅包含此CA证书的信任库.
>在安装客户端期间,服务器会发布由我们的CA证书签名的客户端证书(其客户端ID为CN).
>客户端随后可以彼此连接,并且在建立连接后,将通过验证客户端各自的证书来执行相互客户端身份验证.我们初始化处理客户端身份验证的TrustManager,如下所示:
.
private TrustManager[] getClientCATrustManagers() throws NoSuchAlgorithmException, IOException, KeyStoreException, CertificateException {
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("PKIX");
KeyStore trustStore = getClientCATrustStore();
trustManagerFactory.init(trustStore);
return trustManagerFactory.getTrustManagers();
}
getClientCATrustStore()返回仅包含我们的CA的信任库.
这使我想到了我的问题.我对链验证的理解是,只要链的根是受信任的,并且链上的所有证书都没有过期,则该链被视为有效.我对此担心的是,然后我看到了客户将能够使用其自己的证书来发行新证书的风险.那是潜在的风险吗?如果是,该如何预防?我看到了两个潜在的解决方案:
>我创建了自己的TrustManager来防止这种情况.有没有已经实现过的实现?
>当客户端证书由服务器颁发时,我会以某种方式指定不允许客户端证书颁发自己的证书.这可能吗?如果可以,怎么办?
解决方法:
如果根是受信任的,并且所有中间证书都存在且有效,那么对于证书链有效且受信任的情况,您是正确的.
而且,对于客户自己发行另一个证书的潜在风险,您也是正确的.但是有减轻这种风险的方法.
X509证书(版本3)包含指示其被允许执行或不允许执行的扩展.
例如,您可能会对2个特定部分感兴趣:
>基本约束
>密钥用法
基本约束可确定证书是否为CA,这意味着,如果将其指定为CA本身,则只能用于验证证书签名.它还指定路径长度.这限制了该CA可以签名/颁发的CA中间证书的数量.此路径长度的一个很好的解释是this SO question.这听起来像您希望CA证书上的路径长度为0.
密钥用法指示允许该实体执行的操作.通常,CA证书具有以下关键用法属性:证书签名,CRL签名.非CA或“最终实体”证书可以具有:数字签名,不可否认性,密钥加密,数据加密.
这些扩展名均受RFC5280的约束.
这是重要的部分.为了使这些证书扩展名有意义,必须由应用程序使用它们对其进行检查和实施.
您的客户端应用程序可以查看扩展名,并验证其他客户端证书的路径长度为0(这意味着CA与客户端证书之间没有中间证书).