Home > Java, Uncategorized > Avoiding the “javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated” with HttpClient

Avoiding the “javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated” with HttpClient

This post has moved here: http://javaskeleton.blogspot.com/2010/07/avoiding-peer-not-authenticated-with.html

Categories: Java, Uncategorized Tags: , , ,
  1. November 18, 2010 at 03:13

    Works like a charm!
    Thanks!

  2. Sharon
    December 2, 2010 at 07:27

    I encountered “Cannot instantiate the type SSLSocketFactory” in the row:

    SSLSocketFactory ssf = new SSLSocketFactory(ctx);

    Thanks for your help~!!

  3. December 2, 2010 at 08:58

    Hi Sharon,

    You are probably trying to instantiate a wrong SSLSocketFactory. The one you need is org.apache.http.conn.ssl.SSLSocketFactory and you probably imported the abstract javax.net.ssl.SSLSocketFactory. Sorry about this, I should have made this more clear in my post.

    Here’s an overview of the import statements as they should appear at the top of your class:
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    import org.apache.http.client.HttpClient;
    import org.apache.http.conn.ClientConnectionManager;
    import org.apache.http.conn.scheme.Scheme;
    import org.apache.http.conn.scheme.SchemeRegistry;
    import org.apache.http.conn.ssl.SSLSocketFactory;
    import org.apache.http.impl.client.DefaultHttpClient;

  4. Sosn
    December 20, 2010 at 16:57

    Thanks!
    I don’t use Apache HttpClient, but was able to adapt the code because your explanations were very clear.

  5. Eyal Schneider
    December 29, 2010 at 10:29

    Nicely explained, and even works great for me.
    Thanks!

  6. January 6, 2011 at 10:44

    Very useful article.

    Thank you very much Mathias.

  7. Ranjan
    January 22, 2011 at 10:44

    Hi, Thanks for a very vice article.
    I also had a similar issue when i was trying to use https proxy params.Though
    when i use this piece of code

    ProxySelectorRoutePlanner routePlanner = new ProxySelectorRoutePlanner(
    httpClient.getConnectionManager().getSchemeRegistry(),
    ProxySelector.getDefault());
    ((DefaultHttpClient)httpClient).setRoutePlanner(routePlanner);

    intead of this piece

    HttpHost proxy = new HttpHost(httpsProxyHost,
    Integer.valueOf(httpsProxyPort), “https”);
    httpClient.getParams().setParameter(DEFAULT_PROXY, proxy);

    I automatically got routed through proper connection.I wonder if u could help me with it.

    • January 22, 2011 at 12:24

      Hi Ranjan,

      If you use the ProxySelectorRoutePlanner you will use the default JRE ProxySelector, which looks at the proxy configuration of the operating system. I don’t understand what you need help with, since you say your connection works?

  8. Gautam
    January 29, 2011 at 02:00

    Not sure why it does not work for me. It still gives me the following exception.

    javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
    at com.ibm.jsse2.ec.getPeerCertificates(ec.java:114)
    at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128)
    at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:399)
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:143)
    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:149)
    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:108)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:415)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:731)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:709)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:700)

    • January 29, 2011 at 09:29

      Hi Gautam,

      Are you sure you put in the following line: ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);? It also looks like you’re using the IBM JSSE. I didn’t test the code with the IBM JSSE.

  9. February 3, 2011 at 00:00

    This worked perfectly, thanks!

  10. Kim, Sungwon
    February 7, 2011 at 10:11

    Thank u very much mathiasdegroof!

    Your explain is very clear and useful.

  11. Makgati
    February 10, 2011 at 19:13

    Hi.

    I did step by step but I get the exception. I am actually using the Apache HTTP 4.0.1 version.

    Error Below:

    EXCEPTION WHILE SENDING THE HANDSHAKE : = peer not authenticated
    javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
    at com.sun.net.ssl.internal.ssl.SSLSessionImpl.getPeerCertificates(Unknown Source)
    at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128)
    at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:391)
    at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:489)
    at org.apache.http.conn.scheme.SchemeSocketFactoryAdaptor.connectSocket(SchemeSocketFactoryAdaptor.java:62)
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:148)
    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:149)
    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:121)
    at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:562)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:415)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:700)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:625)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:603)
    at com.paypal.struts.transaction.PayPalMassPayAPIListener.execute(PayPalMassPayAPIListener.java:84)
    at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:421)
    at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:226)
    at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1164)
    at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:415)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.paypal.servlets.filters.SecurityFilter.doFilter(SecurityFilter.java:85)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at com.opensymphony.module.sitemesh.filter.PageFilter.parsePage(PageFilter.java:118)
    at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
    at java.lang.Thread.run(Unknown Source)

    I just call the wrapper and do as the IPN listener has to do:

    HttpClient httpClient = new DefaultHttpClient();
    httpClient = wrapClient(httpClient);

    • February 10, 2011 at 22:17

      I think you missed one step. Are you sure you put this line in your code:
      ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

      You say you use this in the IPN listener. The IPN listener does a call to the PayPal server, so you shouldn’t need to bypass the certificate validation: PayPal will always have a valid SSL certificate. What URL are you calling?

  12. Makgati
    February 11, 2011 at 13:07

    Ok…I am actually testing my IPN Listener againts the PayPal IPN server, (ipn.sanbox.paypal.com:443)…so I am still testing.
    I thought I will be able to bypass the certificate validation by the PayPal IPN sandbox. From what you say, it is unlikely.
    I did this, http://forums.oscommerce.com/topic/166092-paypal-ipn-dummies-guide/, and I got a:
    javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
    Then I tried what you said and I then got:
    javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated.

    Any ideas?

  13. Makgati
    February 13, 2011 at 16:42

    mathiasde, if you test using the IPN simulator,https://developer.paypal.com/cgi-bin/devscr?cmd=_ipn-link-session and then check your network traffic, you will see that the server, ipn.sanbox.paypal.com is trying to connect send through a notification to your listener, not http://www.sanbox.paypal.com. The latter IP address is 216.113.191.33 and while the former is 216.113.191.82. The latter is correct.
    I do get my payment correctly from ipn.sanbox.paypal.com and I then get the above error thrown at the line:

    String rc = getRC(client.execute(post)).trim(); as in your IPN link…

    • February 13, 2011 at 18:17

      It’s possible that the request to your server is originating from ipn.sandbox.paypal.com. That doesn’t mean that you should use that URL to validate the call. There is no http or https server running on ipn.sandbox.paypal.com (just go to https://ipn.sandbox.paypal.com/ with your web browser), so there is no way your request will succeed. If on the other hand you go to https://www.sandbox.paypal.com, you will see there is a https server running on that address. You don’t have to believe me, but you will never get it to work if you use the ipn.sanbox.paypal.com address. The only correct sandbox URL is https://www.sandbox.paypal.com/cgi-bin/webscr

  14. TH Lim
    February 24, 2011 at 07:13

    Hi,

    Thanks for your tip. However, I have another question. How do I handle client certificate authentication? I created a CSR and have it signed and returned by the server CA certificate. How do I include this signed CSR in the client side https connection? The whole process worked with Chrome and Firefox. I want to do the same using Httpclient 4.x.

    Thanks.

    • February 24, 2011 at 10:10

      Hi,

      I’ve never had to do this myself, but the steps would probably be like this:
      1. Import the key into a local keystore (don’t forget to import the trusted CA certificates as well so you have the whole certificate chain in there).
      2. Create a KeyStore object and point this to your local keystore file.
      3. Create a KeyManagerFactory and init this with your KeyStore object and the password to your KeyStore
      4. Call the getKeyManagers() method on the KeyManagerFactory and use those in the init() method of the SSLContext (where it says “null” in the above example)

      Hope this works for your.

  15. TH Lim
    February 25, 2011 at 10:31

    Thanks for the prompt reply. With my limited knowledge on this subject, I don’t quite understand the purposes of step 1 and 3. For step 1, I don’t think the browser (e.g. Chrome) has my trusted CA cert becoz the trusted cert for signing CSR that I loaded in the server is not certified by “Verisign”. For step 3, what is the purpose of KeyManager?

    What I did was, I created a self-signed cert (SSC) using keytool. In my code, I loaded the SSC from keystore and get its private and public keys. Using these keys I created a CSR and pass it to the server for signing. When I receive the new certificate from the server I saved it into the keystore. Using the SSLContext with the keystore, I made the SSL connection. As expected, the connection threw the “javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated”.

    I searched the web and trying to look for the process of how a browser handle client side SSL connection. I wonder if you can advice me where to look for more info.

    • February 25, 2011 at 20:57

      I suppose you’re right. Like I said, I’ve never done this before myself.

      Your code should probably look something like this:

      public class WebClientDevWrapper {

      public static HttpClient wrapClient(HttpClient base) {
      try {
      SSLContext ctx = SSLContext.getInstance(“TLS”);
      X509TrustManager tm = new X509TrustManager() {

      public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {
      }

      public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {
      }

      public X509Certificate[] getAcceptedIssuers() {
      return null;
      }
      };
      KeyStore ks = KeyStore.getInstance(“jks”);
      String keystorePassord = “pass”;
      ks.load(new FileInputStream(“c:/keystore_file”), keystorePassord.toCharArray());
      KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
      kmf.init(ks, keystorePassord.toCharArray());
      ctx.init(kmf.getKeyManagers(), new TrustManager[] { tm }, null);
      SSLSocketFactory ssf = new SSLSocketFactory(ctx);
      ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
      ClientConnectionManager ccm = base.getConnectionManager();
      SchemeRegistry sr = ccm.getSchemeRegistry();
      sr.register(new Scheme(“https”, ssf, 443));
      return new DefaultHttpClient(ccm, base.getParams());
      } catch (Exception ex) {
      ex.printStackTrace();
      return null;
      }
      }
      }

      If you still get errors with that code, please look at the javadoc at the top of the following class: http://svn.apache.org/viewvc/httpcomponents/oac.hc3x/trunk/src/contrib/org/apache/commons/httpclient/contrib/ssl/AuthSSLProtocolSocketFactory.java?view=markup which will tell you how to import the correct keys into your keystore.

      Hope this works for you.

  16. TH Lim
    March 1, 2011 at 06:29

    Your tip was very helpful. I finally got it figured. The key to the solution lied in KeyManager and TrustManager. KeyManager to choose the right certificate to use in the SSL connection and empty TrustManager extension to enable the client to connect to the server. Workable (not tested to work in all context) codes follow,

    import java.io.IOException;
    import java.net.Socket;
    import java.security.InvalidKeyException;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.KeyStore;
    import java.security.NoSuchAlgorithmException;
    import java.security.NoSuchProviderException;
    import java.security.Principal;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.security.SignatureException;
    import java.security.cert.CertificateException;
    import java.security.cert.CertificateExpiredException;
    import java.security.cert.CertificateFactory;
    import java.security.cert.X509Certificate;
    import java.util.ArrayList;
    import java.util.List;

    import javax.net.ssl.KeyManager;
    import javax.net.ssl.KeyManagerFactory;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509ExtendedKeyManager;
    import javax.net.ssl.X509TrustManager;
    import javax.security.auth.x500.X500Principal;

    import org.apache.commons.lang.RandomStringUtils;
    import org.apache.commons.lang.StringUtils;
    import org.apache.http.HttpResponse;
    import org.apache.http.NameValuePair;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.entity.UrlEncodedFormEntity;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.conn.scheme.Scheme;
    import org.apache.http.conn.ssl.SSLSocketFactory;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.message.BasicNameValuePair;
    import org.apache.http.util.EntityUtils;
    import org.bouncycastle.asn1.DERSet;
    import org.bouncycastle.jce.PKCS10CertificationRequest;
    import org.bouncycastle.util.encoders.Base64;

    public class TestClientSSLConnection
    {

    public static void main() throws Exception
    {

    HttpClient client = new DefaultHttpClient();
    HttpPost createCertPost = new HttpPost(“http://localhost:8080/createUser”);
    final KeyPair keyPair = KeyPairGenerator.getInstance(“RSA”).generateKeyPair();

    List formParams = new ArrayList();
    formParams.add(new BasicNameValuePair(“userName”, generateRandomString()));
    String generatedGivenName = generateRandomString();
    formParams.add(new BasicNameValuePair(“givenName”, generatedGivenName));
    String generatedFamilyName = generateRandomString();
    formParams.add(new BasicNameValuePair(“familyName”, generatedFamilyName));
    formParams.add(new BasicNameValuePair(“email”, generateRandomEmail()));
    String generatedOrganization = generateRandomString();
    formParams.add(new BasicNameValuePair(“org”, generatedOrganization));
    //formParams.add(new BasicNameValuePair(“keygen”, new String(Base64.encode(createCertRequest(privateKeyEntry.getPrivateKey(), masterCert.getPublicKey()).getEncoded()))));
    formParams.add(new BasicNameValuePair(“keygen”, new String(Base64.encode(createCertRequest(keyPair.getPrivate(), keyPair.getPublic()).getEncoded()))));

    UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams, “UTF-8”);

    createCertPost.setEntity(entity);
    createCertPost.setHeader(“User-Agent”,
    “Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.558.0 Safari/534.10”);

    HttpResponse res = null;
    try
    {
    res = client.execute(createCertPost);
    }
    catch (IOException e)
    {
    fail(“Failed to connect to server.”); // fail(…) is a method in JUnit’s Testcase. Use log instead if not using Testcase. Same for others.
    }

    if (res.getStatusLine().getStatusCode() != 200)
    {
    fail(“Failed to submit new user information.”);
    }

    String responseBody = EntityUtils.toString(res.getEntity());

    HttpGet retrieveCertGet = new HttpGet(“http://localhost:8080/retrieveMyCertificate?&certId=” + certId);

    try
    {
    res = client.execute(retrieveCertGet);
    if (res.getStatusLine().getStatusCode() != 200)
    {
    fail(“Failed to retrieve signed certificate.”);
    }
    }

    catch (Exception e)
    {
    fail(“Failed to retrieve user certificate.”);
    LOG.fatal(e);
    }

    final X509Certificate certificateResponse = (X509Certificate)CertificateFactory.getInstance(“X.509”)
    .generateCertificate(res.getEntity().getContent());

    try
    {
    certificateResponse.checkValidity();
    }
    catch(Exception e)
    {
    fail(“Signed certificate failed validity check.”);
    }

    X509TrustManager tm = new X509TrustManager()
    {

    public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException
    {
    }

    public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException
    {
    // leaving empty to denote accepting all server certificates
    }

    public X509Certificate[] getAcceptedIssuers()
    {
    return null;
    }
    };

    SSLContext ctx = null;
    try
    {
    ctx = SSLContext.getInstance(“TLS”);
    }
    catch (Exception e)
    {
    fail(“Failed to create SSL socket factory.”);
    }

    KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    X509ExtendedKeyManager keyManager = new X509ExtendedKeyManager()
    {
    @Override
    public String[] getClientAliases(String s, Principal[] principals)
    {
    return new String[0];
    }

    @Override
    public String chooseClientAlias(String[] strings, Principal[] principals, Socket socket)
    {
    return “”;
    }

    @Override
    public String[] getServerAliases(String s, Principal[] principals)
    {
    return new String[0];
    }

    @Override
    public String chooseServerAlias(String s, Principal[] principals, Socket socket)
    {
    return null;
    }

    @Override
    public X509Certificate[] getCertificateChain(String s)
    {
    // use the signed CSR to connect to the server
    return new X509Certificate[] {certificateResponse};
    }

    @Override
    public PrivateKey getPrivateKey(String s)
    {
    return keyPair.getPrivate();
    }
    };
    ctx.init(new KeyManager[] {keyManager}, new TrustManager[] {tm}, null);
    SSLSocketFactory ssf = new SSLSocketFactory(ctx);
    ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
    HttpGet secureLogon = new HttpGet(“https://localhost:8443/success.html”);
    client.getConnectionManager().getSchemeRegistry().register(new Scheme(“https”, ssf, 8443));

    res = client.execute(secureLogon);
    if (res.getStatusLine().getStatusCode() != 200)
    {
    fail(“Failed to connect to secure site”);
    }
    }

    private PKCS10CertificationRequest createCertRequest(PrivateKey privateKey, PublicKey publicKey) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException, NoSuchProviderException
    {
    return new PKCS10CertificationRequest(“SHA512withRSA”,
    new X500Principal(“O=as UID=cert1 CN=Test V3 Certificate”),
    publicKey,
    new DERSet(),
    privateKey);
    }

    private String generateRandomEmail()
    {
    return “testcase_” + RandomStringUtils.randomAlphabetic(10) + “@localtest.com”;
    }

    private String generateRandomString()
    {
    return “testcase_” + RandomStringUtils.randomAlphabetic(10);
    }

    }

    • March 1, 2011 at 09:13

      I’m glad you got it to work. Thank you for posting your code, I’m sure it will help someone out in the future!

  17. yzhao
    March 27, 2011 at 07:45

    I’m from China.Thanks a lot!

  18. Richard Jose
    March 29, 2011 at 21:59

    TH Lim,

    setHostnameVerifier is deprecated, can you tell me how will your code change accordingly? I am kind of confused.

    Richard

  19. Richard Jose
    March 30, 2011 at 02:06

    Actually I got around my earlier question by doing this:
    SSLSocketFactory ssf = new SSLSocketFactory(ctx,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER );

    instead of ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

    Now I have another problem with httpclient’s authscope method. I was thinking it will establish a permanent session with the host that I am specifying but it doesn’t seem to. I am not sure how to establish a session to talk to the REST service I am talking to within the same class.

    I get the following error:

    executing request GET https://dam-vchg01.land.virtual/vCenter-CB/api/costModels/ HTTP/1.1
    —————————————-
    HTTP/1.1 200 OK
    Response content length: 318

    Here is my code:
    public class ClientAuthentication {

    public static void main(String[] args) throws Exception {

    DefaultHttpClient httpclient = HttpClientIgnoreInvalidSSLCertificate.createClient();
    //DefaultHttpClient httpclient = new DefaultHttpClient();

    try {

    httpclient.getCredentialsProvider().setCredentials(
    new AuthScope(“dam-vchg01.land.virtual”, 443),
    new UsernamePasswordCredentials(“rjose”, “rjose6345”));

    HttpGet httpget = new HttpGet(“https://dalm-vchg01.land.virtual/vCenter-CB/api/costModels/”);

    System.out.println(“executing request” + httpget.getRequestLine());
    HttpResponse response = httpclient.execute(httpget);
    HttpEntity entity = response.getEntity();

    System.out.println(“—————————————-“);
    System.out.println(response.getStatusLine());
    if (entity != null) {
    System.out.println(“Response content length: ” + entity.getContentLength());

    try {

    BufferedReader reader = new BufferedReader(
    new InputStreamReader(response.getEntity().getContent()));
    String line = “”;

    while ((line=reader.readLine())!= null)
    {

    System.out.println(line);
    }

    } catch (IOException ex) {

    ex.printStackTrace();
    throw ex;

    } catch (RuntimeException ex) {

    httpget.abort();
    throw ex;

    } finally {

    }

    }
    EntityUtils.consume(entity);
    } finally {

    httpclient.getConnectionManager().shutdown();
    }
    }
    }

    Please tell me how to get around this. Is there something that i am missing.

    Thanks,
    Richard

    • March 30, 2011 at 10:58

      Ok I see 3 questions here:

      1. They must have deprecated the setHostnameVerifier() in a recent version, because it wasn’t deprecated in the version I used when I wrote the article (v4.0.1, which was the latest version at that time). It’s good that you found a workaround.
      2. I don’t know what you mean by a “permanent session”. There is no such thing in HTTP. Sessions are implemented on the server, either by passing a cookie or a session id parameter in each request. Maybe you mean TCP connection reuse? This is something that HTTPClient will try to do by default (see http://hc.apache.org/httpcomponents-client-ga/tutorial/html/httpagent.html for more info on how to modify this behavior).
      3. You also say you get an error, but I don’t see any errors posted, only a HTTP/1.1 200 OK, which means everything went well…

  20. Beena
    April 4, 2011 at 05:05

    I’m still getting the Peer not authenticated exception, following the code above. Below is the exception and snippet of code I’m using. Any ideas? Thanks much for your help

    javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
    at com.sun.net.ssl.internal.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:352)
    at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128)
    at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:339)
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:123)
    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:147)
    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:108)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:415)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641)

    public void sendMessage(String url) throws Exception {

    X509TrustManager tm = new X509TrustManager() {
    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
    return null;
    }

    public void checkClientTrusted( java.security.cert.X509Certificate[] chain,
    String authType)
    throws
    java.security.cert.CertificateException {
    // TODO Auto-generated method stub

    }

    public void checkServerTrusted ( java.security.cert.X509Certificate[] chain,
    String authType)
    throws java.security.cert.CertificateException {
    // TODO Auto-generated method stub

    }
    };

    long token = System.currentTimeMillis();

    log.info(TAG + “sendMessage() ” + token + ” url -> ” + url);

    //System.setProperty(“sun.security.ssl.allowUnsafeRenegotiation”, “true”);

    KeyManagerFactory kmf =
    KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    kmf.init(keyStore, KEYSTORE_PASS.toCharArray());

    DefaultHttpClient dhc = new DefaultHttpClient();

    SSLContext sc = SSLContext.getInstance(“TLS”);
    sc.init(kmf.getKeyManagers(), new TrustManager[]{tm}, null);

    SSLSocketFactory ssf = new SSLSocketFactory(sc);
    ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
    //SSLSocketFactory ssf = new SSLSocketFactory(keyStore, KEYSTORE_PASS, null);
    Scheme s = new Scheme(“https”, ssf, 443);
    ClientConnectionManager ccm = dhc.getConnectionManager();
    ccm.getSchemeRegistry().register(s);

    HttpGet hp = new HttpGet(url);

    HttpResponse hr = dhc.execute(hp);

    log.info(TAG + “sendMessage() ” + token + ” response -> ” + hr.getStatusLine());
    log.info(TAG + “sendMessage() ” + token + ” response -> ” + hr.getEntity().getContent().toString());

    ccm.shutdown();
    }

  21. April 4, 2011 at 09:03

    Hi Beena,

    I tried your code, except for the KeyManagerFactory, and it works for me. So I assume the server is rejecting your clients certificate. This means it’s the client authentication that’s failing and not the server authentication. You’ll need to make sure that your keystore contains a certificate that is accepted by the server you are connecting to.

    Hope this helps.

  22. Art
    May 1, 2011 at 19:34

    Folks, it works!!! Just saved myself a ton of time and effort. Thank you!

  23. VSZ
    May 11, 2011 at 21:30

    Hello,
    Your code was very helpful. My legal department is asking whether you could license this code snippet to us or make some statement about it being public domain. If you attach an Apache 2.0 or BSD style license, that would be easiest.
    Thank you!
    — Victor

    • May 12, 2011 at 08:39

      Hi Victor,

      I wouldn’t worry too much about it: these licenses are generally used for libraries and this is just a code snippet. Anyone is free to use it in any way they want. I’ll add a comment to the class just to make sure.

      • VSZ
        May 12, 2011 at 17:02

        Hi, and thanks! Even code snippets cannot be used by in a commercial application (at least at our company) unless it’s clearly labeled with a license or public domain statement. Thanks so much for your help!

        — Victor

  24. Thuy Tran
    May 23, 2011 at 05:51

    For those who are still getting “javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated”, you may want to turn on ssl debug (-Djavax.net.debug=ssl) to see what the problem is. For my purpose, I actually don’t want to trust all certs, so I have trusted root certificates in my truststore. However, I will sometimes still get javax.net.ssl.SSLPeerUnverifiedException for a web server that I’ve been able to connect to before. Turning on ssl debug reveals that during the handshake, if my app should lose connection to the server due to Connection reset (e.g. java.net.SocketException: Connection reset), it will throw javax.net.ssl.SSLPeerUnverifiedException. So the exception is misleading. The stacktrace (snippet below) shows this is caused by the jre so unfortunately, we will have to wait for Oracle to fix this issue.

    javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
    at com.sun.net.ssl.internal.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:352)
    at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128)
    at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:390)
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:148)
    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:149)
    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:121)
    at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:562)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:415)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732)

    SSL debug shows SocketException as real cause:

    Thread-12, WRITE: TLSv1 Handshake, length = 113
    Thread-12, handling exception: java.net.SocketException: Connection reset
    Thread-12, SEND TLSv1 ALERT: fatal, description = unexpected_message
    Thread-12, WRITE: TLSv1 Alert, length = 2
    Thread-12, Exception sending alert: java.net.SocketException: Broken pipe
    Thread-12, called closeSocket()
    Thread-12, called close()
    Thread-12, called closeInternal(true)

  25. Shilpa
    July 7, 2011 at 13:31

    HI,

    Can anyone please send me sample code to connect to HTTPS URL with user id/password and download some file. I was able to do this with simple URL without any credential but for login URLs, its returning me SSO page in response 😦 …please advice! I am using HttpClient 4.1 jars.

    MAny THanks
    Shilpa

    • July 7, 2011 at 14:39

      Hi Shilpa,

      This depends on the authentication mechanism used. It is basic authentication or some kind of form-based authentication?

  26. July 8, 2011 at 03:52

    Shilpa,

    This thread is referring to client side HTTPS. From your requirement, what you want to resolve is a typical HTTPS (on server side) connection with a page basic authentication and a download link. There are bits and pieces documentations scattered. It is just tedious to combine them together.

  27. Shilpa
    July 8, 2011 at 07:41

    Thanks for ur responses.

    Yes, it is page basic authentication(single sign on). Sorry about posting my queries here but if you guys know any reference link, please share…it will be great help!!

    THanks again.
    SHilpa

  28. Shilpa
    July 12, 2011 at 14:57

    Thanks mathiasde! I looked at the link, it has 4 types of authentication but couldn’t find anything for CSP authentication type which is used in our SSO 😦

    I also tried NTLM type and did windows authentication setup in my SSO but still no luck ….I am not sure whether am I trying a valid scenario here or is it something which is not possible with HttpClient…

    • July 12, 2011 at 15:49

      Wel you’ll need to figure out what authentication your CSP uses first. CSP isn’t an authentication scheme. Maybe it uses Kerberos, so you could try that…

  29. Shilpa
    July 13, 2011 at 11:50

    hmm need to dig into CSP 🙂 its on customer side so lit slow to get all answers.

    I tried kerberos code as well, but it too return the SSO html page in response 😦 atleast I am not getting any exception so may be there is some hope to work ahead 🙂

  1. November 18, 2010 at 03:19
  2. January 23, 2011 at 13:14
  3. January 24, 2011 at 11:50

Leave a reply to mathiasdegroof Cancel reply