简体   繁体   English

Java7拒绝信任信任库中的证书

[英]Java7 Refusing to trust certificate in trust store

I've a weird problem - a supplier uses TLS SSLv3 with both a self signed client and server certificate. 我有一个奇怪的问题 - 供应商使用TLS SSLv3同时具有自签名客户端和服务器证书。 This hasn't been a problem with Java1.5 and Java1.6 - simply import client certificate and private key into a keystore and the server public certificate into the truststore. 这对Java1.5和Java1.6来说不是问题 - 只需将客户端证书和私钥导入密钥库,将服务器公共证书导入信任库即可。 Everything works fine. 一切正常。 However with Java7 the server certificate fails to be trusted even though the same truststore is being used. 但是,对于Java7,即使使用相同的信任库,也无法信任服务器证书。 I've tried Windows and Red Hat both using Java7 (1.7.03, 04 and 05, x86 and x64 versions) with no success. 我尝试使用Java7(1.7.03,04和05,x86和x64版本)的Windows和Red Hat都没有成功。

I've recreated the keystore/truststore from scratch and they only contain these certificates. 我从头开始重新创建密钥库/信任库,它们只包含这些证书。 The appropriate system properties have been set (javax.net.ssl.keyStore, javax.net.ssl.trustStore) and the key aspect is that the exact same code and configuration runs perfectly in JDK5/6. 已经设置了适当的系统属性(javax.net.ssl.keyStore,javax.net.ssl.trustStore),关键方面是完全相同的代码和配置在JDK5 / 6中完美运行。

I'm at a loss - I can't find any reference to additional checking but I would have thought that the fact the certificate was located in the truststore should mean that it's trusted regardless of being self signed. 我很茫然 - 我找不到任何对额外检查的引用,但我认为证书位于信任库中的事实应该意味着无论是否自签,它都是可信的。

Any help appreciated. 任何帮助赞赏。 Ads 广告

Exception trace: 异常跟踪:

Exception in thread "main" javax.net.ssl.SSLHandshakeException:     sun.security.validator.ValidatorException: PKIX path validation failed:     java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1868)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1338)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:154)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:998)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1294)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:685)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:111)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295)
at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)
at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)
at com.alltria.ypsilon.testing.TestSSL.main(TestSSL.java:65)
Caused by: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:350)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:249)
at sun.security.validator.Validator.validate(Validator.java:260)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1320)
... 13 more
Caused by: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:208)
at java.security.cert.CertPathValidator.validate(CertPathValidator.java:279)
at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:345)
... 19 more
Java Result: 1

The part where the ssl debug fails is trying to validate the server certificate: ssl调试失败的部分是尝试验证服务器证书:

***
%% Invalidated:  [Session-1, SSL_RSA_WITH_RC4_128_SHA]
main, SEND SSLv3 ALERT:  fatal, description = certificate_unknown
main, WRITE: SSLv3 Alert, length = 2
[Raw write]: length = 7
0000: 15 03 00 00 02 02 2E                               .......
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
main, called close()
main, called closeInternal(true)

I actually had a somewhat similar issue, where a Tomcat application would trust the ca cert in the truststore when using Java 1.6 and reject it with java 1.7. 我实际上有一个类似的问题,在使用Java 1.6时,Tomcat应用程序会信任信任库中的ca证书,并使用java 1.7拒绝它。 After adding keyUsage to my ca certificate it works (after reading a bug report, JDK-7018897 : CertPath validation cannot handle self-signed cert with bad KeyUsage ). keyUsage添加到我的ca证书后,它可以正常工作(在阅读错误报告后, JDK-7018897:CertPath验证无法处理带有错误KeyUsage的自签名证书 )。

What I have done (Ubuntu 12.04 x64): 我做了什么(Ubuntu 12.04 x64):

  1. Edit /etc/ssl/openssl.cnf and uncomment keyUsage line in v3_ca section. 编辑/etc/ssl/openssl.cnf并取消注释v3_ca部分中的keyUsage行。
  2. Generate new ca cert from old one with keyUsage included using the command: 使用以下命令生成包含keyUsage旧ca证书:

     openssl x509 -in oldca.pem -clrext -signkey oldca.key -extfile /etc/ssl/openssl.cnf -extensions v3_ca -out newca.pem 
  3. Delete old CA key from truststore and insert the new one. 从信任库中删除旧的CA密钥并插入新的CA密钥。

I have also encountered this situation when dealing with JDK 1.7. 在处理JDK 1.7时我也遇到过这种情况。 If req command is invoked with the -x509 option, it's better to uncomment keyUsage line in v3_ca section and generate the CA again with(see http://wwwneu.secit.at/web/documentation/openssl/openssl_cnf.html ) 如果使用-x509选项调用req命令,最好取消注释v3_ca部分中的keyUsage行并再次生成CA(参见http://wwwneu.secit.at/web/documentation/openssl/openssl_cnf.html

openssl req -new -x509 -days 3650 -keyout ca.key -out ca.crt -config openssl.cnf -extensions v3_ca -batch

And if you use the generated CA certificate to sign other certificate make sure that you also uncomment the item basicConstraints = CA:true and set value to true 如果您使用生成的CA证书签署其他证书,请确保您还取消注释itemConstraints = CA:true并将值设置为true

For some reasons Java 8 doesn't accept self-signed certificate even added to its cacerts store. 由于某些原因,Java 8不接受自签名证书,甚至添加到其cacerts商店。

My workaround for that is to create a custom keystore : 我的解决方法是创建一个自定义密钥库:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -subj "/C=MA/ST=ByExample/L=Test/O=Chapter3/OU=Org/CN=bip70.com" -node s openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -subj "/C=MA/ST=ByExample/L=Test/O=Chapter3/OU=Org/CN=bip70.com" -node s

keytool -import -keystore clientkeystore -file cert.der -alias bip70.com -storepass changeit

then using it in My IDE using as jvm argument: -Djavax.net.ssl.trustStore=clientkeystore 然后在我的IDE中使用它作为jvm参数: -Djavax.net.ssl.trustStore=clientkeystore

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM