Java7 Отказ от доверия сертификату в хранилище доверия
У меня странная проблема: поставщик использует TLS SSLv3 с сертификатом клиента и сервера с самоподпиской. Это не было проблемой с Java1.5 и Java1.6 - просто импортируйте сертификат клиента и закрытый ключ в хранилище ключей и общедоступный сертификат сервера в доверительный магазин.
Все работает нормально.
Однако с Java7 сертификату сервера не удается доверять даже при том, что используется тот же самый супермаркет. Я пробовал Windows и Red Hat с использованием Java7 (версии 1.7.03, 04 и 05, x86 и x64) без успеха.
Я воссоздал хранилище ключей/доверие с нуля, и они содержат только эти сертификаты.
Были установлены соответствующие свойства системы (javax.net.ssl.keyStore, javax.net.ssl.trustStore), и ключевым аспектом является то, что точно такой же код и конфигурация отлично работают в JDK5/6.
Я в недоумении - я не могу найти ссылку на дополнительную проверку, но я бы подумал, что факт, что сертификат находился в доверительном магазине, должен означать, что он доверял независимо от того, что он сам подписан.
Любая помощь оценивается.
Объявления
Трассировка исключения:
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
Часть, в которой сбой 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)
Ответы
Ответ 1
У меня действительно была несколько схожая проблема, когда приложение Tomcat доверяло сертификату ca в доверенности при использовании Java 1.6 и отклоняло его с помощью java 1.7. После добавления keyUsage
в мой сертификат ca он работает (после прочтения отчета об ошибке, JDK-7018897: проверка CertPath не может обрабатывать самозаверяющий сертификат с плохим KeyUsage).
Что я сделал (Ubuntu 12.04 x64):
- Отредактируйте /etc/ssl/openssl.cnf и раскомментируйте
keyUsage
строку в v3_ca
.
-
Сгенерируйте новый сертификат ca из старого с keyUsage
, включенный с помощью команды:
openssl x509 -in oldca.pem -clrext -signkey oldca.key -extfile /etc/ssl/openssl.cnf -extensions v3_ca -out newca.pem
-
Удалите старый ключ CA из доверительного хранилища и вставьте новый.
Ответ 2
Я также столкнулся с этой ситуацией при работе с JDK 1.7.
Если команда req вызывается с параметром -x509, лучше раскомментировать строку keyUsage в разделе v3_ca и снова создать 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
И если вы используете сгенерированный сертификат ЦС для подписания другого сертификата, убедитесь, что вы также раскомментируете элемент basicConstraints = CA: true и установите значение true