title: Safely fixing: javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
body: <p>There are dozens of posts about this issue (javax.net.ssl.SSLPeerUnverifiedException: No peer certificate) but I haven't found anything that works for me.</p>
  
  <p>Many posts (like <a href="https://stackoverflow.com/questions/2642777/trusting-all-certificates-using-httpclient-over-https/6378872#6378872">this</a>, and <a href="https://stackoverflow.com/questions/12136907/how-to-create-an-https-connection/12172000#12172000">this</a>) "solve" this by allowing all certificates to be accepted but, of course, this is not a good solution for anything other than testing.</p>
  
  <p>Others seem quite localized and don't work for me. I really hope that someone has some insight that I lack.</p>
  
  <p>So, my problem: I'm testing on a server accessible only through the local network, connecting via HTTPS. Making the call I need to through the browser works fine. No complaining about certificates and if you check the certificates, it all looks good.</p>
  
  <p>When I try on my Android device, I get <code>javax.net.ssl.SSLPeerUnverifiedException: No peer certificate</code></p>
  
  <p>Here's the code that calls it:</p>
  
  <pre><code>StringBuilder builder = new StringBuilder();
  builder.append( /* stuff goes here*/ );
  
  httpGet.setEntity(new UrlEncodedFormEntity(nameValuePairs));
  ResponseHandler&lt;String&gt; responseHandler = new BasicResponseHandler();
  
  // Execute HTTP Post Request. Response body returned as a string
  HttpClient httpClient = MyActivity.getHttpClient();
  HttpGet httpGet = new HttpGet(builder.toString());
  
  String jsonResponse = httpClient.execute(httpGet, responseHandler); //Line causing the Exception
  </code></pre>
  
  <p>My code for <code>MyActivity.getHttpClient()</code>:</p>
  
  <pre><code>protected synchronized static HttpClient getHttpClient(){
      if (httpClient != null)
          return httpClient;
  
      HttpParams httpParameters = new BasicHttpParams();
      HttpConnectionParams.setConnectionTimeout(httpParameters, TIMEOUT_CONNECTION);
      HttpConnectionParams.setSoTimeout(httpParameters, TIMEOUT_SOCKET);
      HttpProtocolParams.setVersion(httpParameters, HttpVersion.HTTP_1_1);
  
      //Thread safe in case various AsyncTasks try to access it concurrently
      SchemeRegistry schemeRegistry = new SchemeRegistry();
      schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
      schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
      ClientConnectionManager cm = new ThreadSafeClientConnManager(httpParameters, schemeRegistry);
  
      httpClient = new DefaultHttpClient(cm, httpParameters);
  
      CookieStore cookieStore = httpClient.getCookieStore();
      HttpContext localContext = new BasicHttpContext();
      localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
  
      return httpClient;
  }
  </code></pre>
  
  <p>Any help would be much appreciated.</p>
  
  <p><strong>Edit</strong></p>
  
  <p>Also just to mention I've had other SSL issues with another app but adding the <code>SchemeRegistry</code> portion fixed it for me before.</p>
  
  <p><strong>Edit 2</strong></p>
  
  <p>So far I've only tested on Android 3.1, but I need this to work on Android 2.2+ regardless. I just tested on the browser on my Android tab (Android 3.1) and it complains about the certificate. It's fine on my pc browser, but not on the Android browser or in my app.</p>
  
  <p><strong>Edit 3</strong></p>
  
  <p>Turns out the iOS browser also complains about it. I'm starting to think it's a certificate chain issue described here (<a href="https://stackoverflow.com/questions/13862908/ssl-certificate-is-not-trusted-on-mobile-only">SSL certificate is not trusted - on mobile only</a>)</p>