The Webserver I talk to updated its SSL cert and now my app can't talk to it

允我心安 提交于 2019-11-30 09:06:55

问题


The webserver updated its SSL cert to a new verisign signed cert and my java app can no longer connect.

I am using java 5 with a date on the cert file Nov 2006 in /usr/java/jre/lib/security

I get

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1518)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:174)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:168)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:848)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:106)
    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:495)
    at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:433)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:818)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1030)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1057)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1041)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:402)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:170)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:133)

How do I install a new key supplied by the server?

From a different java instance I get

Certificate chain received from eservices3.bus.att.com - 135.38.253.93 was not trusted causing SSL handshake failure.

I assume that it is from the same root problem.

Update Before the remote server was updated this worked with our standard java install. I didn't have to install any certs to get this to work last time around.


回答1:


Java tries to validate the certificate by following the chain of certificates presented by the server, until it finds one it trusts (i.e. one that's present in your cacerts file).

We can verify the chain manually using the OpenSSL command line tools:

simon@lucifer:~$ openssl s_client -connect eservices3.bus.att.com:443
<snipped>
---
Certificate chain
 0 s:/C=US/ST=Georgia/L=Alpharetta/O=ATT Services, Inc./OU=ATTIT/CN=eservices3.bus.att.com
   i:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at https://www.verisign.com/rpa (c)10/CN=VeriSign Class 3 Secure Server CA - G3
---

Now, here's the problem: the issuer (line beginning i:) "VeriSign Class 3 Secure Server CA - G3" is an intermediate certificate, not a root. The AT&T server is misconfigured, and should be sending both its own certificate ("eservices3.bus.att.com") and the intermediate, so that Java can verify the chain all the way to the root.

To illustrate another way, the chain should look like this:

1) VeriSign Class 3 Public Primary Certification Authority - G5 (root)
                               ^
                               | signed by
                               |
2)          VeriSign Class 3 Secure Server CA - G3      (intermediate)
                               ^
                               | signed by
                               |
3)                 eservices3.bus.att.com                     (server)
  • the root (1) is in cacerts - ok
  • the server certificate (3) is presented during the SSL handshake - ok
  • but: Java has no knowledge of the intermediate (2) - so can't verify the chain end-to-end

To fix this, you can either:

  • ask AT&T to fix the server so it sends both the server and intermediate cert during the handshake, or
  • import the intermediate cert into Java's keystore

The first solution is preferable, since it helps everyone (not just you) and is slightly less risky (you might not notice if the intermediate cert became compromised).

If you want to import the cert as a temporary measure, grab it from VeriSign's support pages (it's "Secondary SSL Intermediate CA Certificate"), then:

simon@lucifer:~$ keytool -importcert -alias some_alias_of_your_choosing \
                    -file intermediate_cert_path.crt \
                    -keystore your_cacerts_path
Enter keystore password:  *****
Certificate was added to keystore

To remove the cert (once AT&T get their act together):

simon@lucifer:~$ keytool -delete -alias same_alias_as_before \
                    -keystore your_cacerts_path



回答2:


It sounds as though your server (or application, but more likely the server) doesn't trust the root certificate that verisign has issued this new certificate from. Once you trust that cert, you'll trust all the certs chained to it.

The verisign root CAs can be found at the below link:

http://www.verisign.com/support/roots.html



来源:https://stackoverflow.com/questions/5758812/the-webserver-i-talk-to-updated-its-ssl-cert-and-now-my-app-cant-talk-to-it

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!