使用Java APis验证X509证书

时间:2011-05-26 18:57:07

标签: java

我正在尝试针对java密钥库验证证书,这是我使用的代码如下所示。如果它成功完成,那么我认为验证已经正确完成,否则如果抛出异常,则验证失败。 我担心的是:

以下代码是否足以验证证书?因为我在这里缺少一些东西(比如检查计算机签署的数据给我发送证书?)? 2.是否应核实证书中包含的签名?如果有,怎么样?

提前感谢您的回复! 普拉迪普

// To check the validity of the dates
cert.checkValidity();
//Check the chain
CertificateFactory cf = CertificateFactory.getInstance("X.509");
List<X509Certificate> mylist = new ArrayList<X509Certificate>();          
mylist.add(cert);
CertPath cp = cf.generateCertPath(mylist);
PKIXParameters params = new PKIXParameters(getTrustStore());
params.setRevocationEnabled(false);
CertPathValidator cpv =
      CertPathValidator.getInstance(CertPathValidator.getDefaultType());
PKIXCertPathValidatorResult pkixCertPathValidatorResult =
      (PKIXCertPathValidatorResult) cpv.validate(cp, params);

3 个答案:

答案 0 :(得分:7)

通常,证书将由中间颁发机构颁发,而不是“根”权限(应该在您的信任存储中)。大多数协议鼓励发送证书的“链”,而不仅仅是实体的证书。

您应该添加所有中间证书,以便形成完整的链。

为了确保证书仍然有效,您不应禁用吊销检查。如果您不想检索CRL(可能很大),则颁发者可能会提供OCSP支持。但是,必须通过设置某些系统属性在Java运行时中启用它。

如果路径验证器成功返回,则无需检查其他任何内容。如果证书无效,则会引发异常。

此外,无需明确检查有效日期。这在验证期间发生(使用当前时间,除非您通过PKIXParameters指定时间。)


有关验证的更广泛讨论,包括示例代码,see a previous answer of mine.

答案 1 :(得分:3)

如果您对默认信任设置感到满意(因为它们将用于默认的SSLContext),您可以独立于SSL / TLS构建X509TrustManager并使用if验证您的证书独立地

看起来像这样:

TrustManagerFactory trustManagerFactory =
    TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore)null);
// you could use a non-default KeyStore as your truststore too, instead of null.

for (TrustManager trustManager: trustManagerFactory.getTrustManagers()) {  
    if (trustManager instanceof X509TrustManager) {  
        X509TrustManager x509TrustManager = (X509TrustManager)trustManager;  
        x509TrustManager.checkServerTrusted(...);
    }  
}

(您还应该检查服务器的身份和证书匹配,请参阅RFC 6125 (Representation and Verification of Domain-Based Application Service Identity within Internet Public Key Infrastructure Using X.509 (PKIX) Certificates in the Context of Transport Layer Security (TLS))。)

答案 2 :(得分:0)

您在此处所做的是验证信任库中的任何受信任的CA是否已签署证书(在您的示例cert中)(直接)。
另外,您检查是否到期,但不执行撤销检查 因此,如果cert未被任何受信任的CA签署,您将获得例外 因此,代码足以验证任何受信任的CA是否已签署cert


如果您要参考服务器身份验证,那么帖子中的代码是不够的 此代码仅验证特定证书是否由受信任的CA签名 您没有迹象表明向您发送此证书的“实体”实际上是证书的所有者(即他们拥有与此证书相关联的私钥)。
这是SSL身份验证的一部分,例如,客户端发送使用远程服务器的公钥加密的ClientKeyExchange消息,并确定如果另一方是假的,那么将无法解密该消息