确保颁发的证书不会自行颁发证书

时间:2013-08-22 12:41:42

标签: java certificate x509certificate client-certificates

我需要一些帮助来确保我们的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的信任库。

这引出了我的问题。我对链验证的理解是,只要链的根是可信的并且链中的证书都没有过期,该链被认为是有效的。我对此感到担忧的是,我随后看到客户可以使用自己的证书颁发新证书的风险。 这是一个潜在的风险,如果是这样,我该如何预防呢?我看到了两个可能的解决方案:

  1. 我创建了自己的TrustManager来防止这种情况发生。是否有任何实现已经这样做了?
  2. 当服务器发出客户端证书时,我会以某种方式指定不允许客户端证书颁发自己的证书。这是可能的,如果是的话,怎么样?

1 个答案:

答案 0 :(得分:4)

如果根目录是可信的,并且所有中间证书都存在且有效,那么您对证书链的有效性和可信度是正确的。

对于客户自行发行另一个证书的潜在风险,您也是正确的。但是有一些方法可以减轻这种风险。

X509证书(版本3)包含指示允许做或不做的扩展。

例如,您可能会对以下两个特定部分感兴趣:

  • 基本约束

  • 密钥用法

“基本约束”标识证书是否为CA,这意味着只有在证书签名为CA本身时才能用于验证证书签名。它还指定路径长度。这限制了此CA可以签名/颁发的CA中间证书的数量。这个路径长度的一个很好的解释是this SO question。听起来你想要CA证书上的路径长度为0。

密钥用法表示允许该实体执行的操作。通常,CA证书具有以下密钥用法属性:证书签名,CRL签名。鉴于非CA或“最终实体”证书可以具有:数字签名,不可否认,密钥加密,数据加密。

这些扩展程序均由RFC5280管理。

这是重要的部分。对于这些证书扩展意味着什么,它们必须由应用程序使用它们进行检查和强制执行。

您的客户端应用程序可以查看扩展并验证其他客户端证书的路径长度是否为0(表示CA和客户端证书之间没有中间证书)。