使用Java API验证X509证书

使用Java API验证X509证书,java,Java,我试图根据java密钥存储验证证书,下面是我使用的代码。如果它成功完成,那么我假设验证已经正确通过,否则如果抛出异常,那么验证将失败。 我关注的是: 下面的代码是否足以验证证书?在这里,我是否遗漏了一些东西(比如检查发送给我证书的计算机签名的数据?)? 2.是否应验证证书中包含的签名?如果是,如何进行 提前感谢您的回复! 普拉迪普 //检查日期的有效性 证书校验有效性(); //检查链条 CertificateFactory cf=CertificateFactory.getInstance(“

我试图根据java密钥存储验证证书,下面是我使用的代码。如果它成功完成,那么我假设验证已经正确通过,否则如果抛出异常,那么验证将失败。 我关注的是:

下面的代码是否足以验证证书?在这里,我是否遗漏了一些东西(比如检查发送给我证书的计算机签名的数据?)? 2.是否应验证证书中包含的签名?如果是,如何进行

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

//检查日期的有效性
证书校验有效性();
//检查链条
CertificateFactory cf=CertificateFactory.getInstance(“X.509”);
List mylist=new ArrayList();
mylist.add(证书);
CertPath cp=cf.generateCertPath(mylist);
PKIXParameters params=新的PKIXParameters(getTrustStore());
参数setRevocationEnabled(false);
CertPathValidator cpv=
CertPathValidator.getInstance(CertPathValidator.getDefaultType());
PKIXCertPathValidatorResult PKIXCertPathValidatorResult=
(PKIXCertPathValidatorResult)cpv.validate(cp,params);

您在这里所做的是验证证书(在您的示例中为
证书
)是否已由信任库中的任何受信任CA签署(直接)。
此外,您还可以检查过期情况,但不会执行吊销检查。
因此,如果
证书
未由任何受信任的CA签名,您将得到一个例外。
因此,该代码足以验证
cert
是否已由任何受信任的CA签名


如果您指的是服务器身份验证,那么帖子中的代码是不够的。
此代码仅验证特定证书是否由受信任的CA签名。
但是,您没有说明发送此证书的“实体”是否实际是证书的所有者(即他们拥有与此证书关联的私钥)。

这是SSL身份验证的一部分,例如,客户端发送用远程服务器的公钥加密的
ClientKeyExchange
消息,并确定如果另一方是假的,则无法解密消息。通常,证书将由中间颁发机构而不是“根”权限(这是信任存储中的所有权限)。大多数协议都鼓励发送证书的“链”,而不仅仅是实体的证书

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

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

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

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



对于验证的更广泛讨论,包括示例代码,

如果您对默认信任设置感到满意(因为它们将用于默认的
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(...);
    }  
}

(还应检查服务器的标识和证书匹配,请参阅。)

感谢您的快速响应!以上代码是否足以验证证书本身?我的意思是,如果我从服务器获得此证书,并执行上述检查,我是否可以安全地假设服务器的证书有效,并且服务器就是它所说的服务器。谢谢,非常感谢您的帮助。更新答案。希望这有帮助psThat确实有帮助。我正在尝试为SSH实现服务器身份验证。因此,在初始交换期间,一旦我从服务器获得证书,我将尝试验证它以确保服务器不是伪造的,并执行与SSL执行相同的验证过程类似的验证过程。那么这是否意味着SSH将负责服务器aut密钥交换期间的身份验证(证书交换前)我所要做的就是确保证书是有效的?感谢您的回复,如果这些问题看起来很愚蠢,我表示歉意。我刚刚开始挖掘SSH工作流:)如果SSH可以配置证书信任库,那么如果它与SSL一样工作,SSH必须验证传递证书的同一实体是否也wns匹配的私钥。啊!这正是我不确定如何实现的。这意味着我必须拥有此实体的公钥作为设置权限的一部分?如果不是,如何通过X.509证书的字段实现。我收集的签名字段是由CA加密的签名,而不是传递给我此证书的实体有什么建议吗?谢谢!谢谢您的回复!您的意思是我必须将所有中间证书添加到证书列表中(mylist.add(cert);)然后使用CertPath创建一个链?谢谢!我们需要设置java运行时的哪些属性来启用证书的吊销检查。??为什么?JSSE已经为您完成了所有这些。@EJP,请您详细说明JSSE是如何做到这一点的。谢谢。呃,
。@PaulDraper第一个参数是X509Certificate的数组e、 第二个参数是密钥交换算法(例如“RSA”),另请参见X509TrustManager的Javadoc注意,如果TrustManagerFactory没有trustManager,则此代码不会引发异常,从而接受证书
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(...);
    }  
}