SSL "Peer Not Authenticated" error with HttpClient 4.1

113,856

Solution 1

If the server's certificate is self-signed, then this is working as designed and you will have to import the server's certificate into your keystore.

Assuming the server certificate is signed by a well-known CA, this is happening because the set of CA certificates available to a modern browser is much larger than the limited set that is shipped with the JDK/JRE.

The EasySSL solution given in one of the posts you mention just buries the error, and you won't know if the server has a valid certificate.

You must import the proper Root CA into your keystore to validate the certificate. There's a reason you can't get around this with the stock SSL code, and that's to prevent you from writing programs that behave as if they are secure but are not.

Solution 2

This is thrown when

... the peer was not able to identify itself (for example; no certificate, the particular cipher suite being used does not support authentication, or no peer authentication was established during SSL handshaking) this exception is thrown.

Probably the cause of this exception (where is the stacktrace) will show you why this exception is thrown. Most likely the default keystore shipped with Java does not contain (and trust) the root certificate of the TTP that is being used.

The answer is to retrieve the root certificate (e.g. from your browsers SSL connection), import it into the cacerts file and trust it using keytool which is shipped by the Java JDK. Otherwise you will have to assign another trust store programmatically.

Solution 3

keytool -import -v -alias cacerts -keystore cacerts.jks -storepass changeit -file C:\cacerts.cer
Share:
113,856

Related videos on Youtube

IAmYourFaja
Author by

IAmYourFaja

my father is a principal at burgoyne intnl and got me this job programming lisp and development. I aspire to unittesting with a concentration in mobile platforms.

Updated on March 23, 2020

Comments

  • IAmYourFaja
    IAmYourFaja about 4 years

    I am building a simple app monitor to poll one of our API URLs and email us if it can't get a HTTP 200 status code from the response (this would indicate our API is down for some reason).

    I am using HttpClient 4.1 (this is important because its API differs greatly from 3.x).

    Our API is secure with SSL, however entering:

    http://example.com/our-api

    into a web browser redirects you to

    https://example.com/our-api

    Without causing any errors.

    When HttpClient attempts to hit this URL (http://example.com/our-api), it fails with a javax.net.ssl.SSLPeerUnverifiedException exception with a message stating:

    peer not authenticated

    I see this happening a lot for other people as is evidenced by this post (which also provides some ways of circumventing this problem - a solution that I am going to try and implement tonight in fact).

    What this other post (and the other similar ones to it) do not do is explain why this is happening in the first place! So, rather than ask "how do I fix this?" I figured I would ask "why is this happening?" Before I go barging ahead with one of the proposed solutions, I'd like to know what the problem is that I'm attempting to fix ;-)

    • Maarten Bodewes
      Maarten Bodewes almost 12 years
      Could you post the full stack trace?
    • user207421
      user207421 almost 12 years
      It should be noted that this message must be due to strange programming in the HttpClient. There would have been a prior SSLException 'handshake failure', and this is what should have been thrown. Evidently execution continued to an SSLSession.getPeerCertificate() call, which is the only API that throws the exception in the title.
  • Maarten Bodewes
    Maarten Bodewes almost 12 years
    Most of the time the SSL server will send the chain up to but not including the root certificate. So most of the time you won't have to import the whole chain into the keystore. You should however explicitly trust the root certificate.
  • Jim Garrison
    Jim Garrison almost 12 years
    @owlstead yes, usually you need to import only the Root CA; answer edited.
  • nurettin
    nurettin over 7 years
    I imported the certificate (base64 version) into the key store under lib\security\cacerts but java still gives the same error. When I imported it into windows trusted certificates store, chrome stopped giving errors. But when I did it with java keytool it still can't connect.
  • Hsehdar
    Hsehdar over 6 years
    In case the server is using AES_256 cipher suites only then client should have JCE Unlimited Strength Jurisdiction Policy Files