gpt4 book ai didi

Java/Keystore 验证签名证书

转载 作者:搜寻专家 更新时间:2023-11-01 00:57:39 25 4
gpt4 key购买 nike

我正在研究嵌入式 jetty 服务器和客户端之间的客户端证书身份验证。他们都使用 keystore 。客户端证书由 CA 签名的服务器证书签名。 Jetty 使用 2 种方法来验证客户端证书,javax.net.ssl.SSLEngine,这似乎有效,他们也使用上面的代码。

List<X509Certificate> certList = Certificate chain sent by the client
KeyStore truststore = server's truststore

//No use of CRL/OSCP/CRLDP
_crls = null;
_enableOCSP = false;
_enableCRLDP = false;

try{
X509CertSelector certSelect = new X509CertSelector();
certSelect.setCertificate((X509Certificate) certList.get(0));

// Configure certification path builder parameters
PKIXBuilderParameters pbParams = new PKIXBuilderParameters(truststore, certSelect);
pbParams.addCertStore(CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList)));

// Set maximum certification path length
pbParams.setMaxPathLength(-1);

// Enable revocation checking
pbParams.setRevocationEnabled(true);

// Set static Certificate Revocation List
if (_crls != null && !_crls.isEmpty())
pbParams.addCertStore(CertStore.getInstance("Collection", new CollectionCertStoreParameters(_crls)));

// Enable On-Line Certificate Status Protocol (OCSP) support
if (_enableOCSP)
Security.setProperty("ocsp.enable","true");

// Enable Certificate Revocation List Distribution Points (CRLDP) support
if (_enableCRLDP)
System.setProperty("com.sun.security.enableCRLDP","true");

// Build certification path
CertPathBuilderResult buildResult = CertPathBuilder.getInstance("PKIX").build(pbParams);

// Validate certification path
CertPathValidator.getInstance("PKIX").validate(buildResult.getCertPath(),pbParams);
}catch(GeneralSecurityException gse){
...
}

当然我必须使用第二种方式......那么让我们专注于这段代码,这是验证签名证书的好方法吗?这是我的 keystore 的转储:

客户端 keystore :

Entry type: PrivateKeyEntry 
Certificate chain length: 2
Certificate[1]:
Owner: EMAILADDRESS=truc@ok.com, CN=Servlet, OU=dev, O=Imbasoft, ST=Ile-de-France, C=FR
Issuer: EMAILADDRESS=contact@greenpacs.com, CN=Greenpacs, OU=dev, O=Imbasoft, L=Bondy, ST=Ile-de-France, C=FR
...

Certificate[2]:
Owner: EMAILADDRESS=contact@greenpacs.com, CN=Greenpacs, OU=dev, O=Imbasoft, L=Bondy, ST=Ile-de-France, C=FR
Issuer: EMAILADDRESS=ghetolay@imbasoft.com, CN=Greenpacs Certificate Authority, OU=dev, O=Imbasoft, ST=Ile-de-France, C=FR
...

服务器信任库:

Entry type: trustedCertEntry

Owner: EMAILADDRESS=contact@greenpacs.com, CN=Greenpacs, OU=dev, O=Imbasoft, L=Bondy, ST=Ile-de-France, C=FR
Issuer: EMAILADDRESS=ghetolay@imbasoft.com, CN=Greenpacs Certificate Authority, OU=dev, O=Imbasoft, ST=Ile-de-France, C=FR

我不确定这些 keystore ,但我尝试了不同的 keystore (将 CA 证书添加到客户端的证书链,将证书添加到信任库),但验证仍然失败。对于这些 keystore ,第一种验证方式 (SSLEngine) 似乎可以工作。

调试输出太大,不能放在这里,但这里是堆栈跟踪:

java.security.cert.CertPathValidatorException: Could not determine revocation status
at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:153)
at sun.security.provider.certpath.PKIXCertPathValidator.doValidate(PKIXCertPathValidator.java:325)
at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:187)
at java.security.cert.CertPathValidator.validate(CertPathValidator.java:267)
at MainClass.main(MainClass.java:75)
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:197)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:255)
at sun.security.provider.certpath.CrlRevocationChecker.buildToNewKey(CrlRevocationChecker.java:583)
at sun.security.provider.certpath.CrlRevocationChecker.verifyWithSeparateSigningKey(CrlRevocationChecker.java:459)
at sun.security.provider.certpath.CrlRevocationChecker.verifyRevocationStatus(CrlRevocationChecker.java:339)
at sun.security.provider.certpath.CrlRevocationChecker.verifyRevocationStatus(CrlRevocationChecker.java:248)
at sun.security.provider.certpath.CrlRevocationChecker.check(CrlRevocationChecker.java:189)
at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:131)
... 4 more

如果我禁用撤销或者如果我将最后一个证书(而不是第一个)设置为 X509CertSelector,代码可以工作,但我不确定我在做什么。

我开始怀疑 jetty 代码,但我不是证书和 SSL 握手方面的专家,所以它也可能来自错误的 keystore /信任库。这就是为什么我之前没有在 Jetty 的板上创建问题并在这里询问,以确保代码需要更改。

此外,了解如何在 Java 中验证签名证书也很有用。

最佳答案

其实我不需要自己做验证。

SSLEngine 已经在做这件事。如果客户端发送了有效证书,您可以使用 getPeerCertificateChain() 获取它:如果客户端没有发送证书或证书无效,getPeerCertificateChain() 将引发异常.

使用 Jetty(或者我猜是任何 Java ServletContainer)你只需要检查 HttpServletRequest 的属性 ["javax.servlet.request.X509Certificate"] 就可以知道客户端是否发送了有效的证书。

我仍然不知道如何用 Java 验证证书,但这个解决方案对我来说已经足够了 :) 我不再需要自己做。感谢布鲁诺!

关于Java/Keystore 验证签名证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12456079/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com