Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"javax.net.ssl.SSLException: Not trusted server certificate" exception in Android

Tags:

java

android

I am getting this exception when I am trying to hit HTTPS URL (.Net Webservice) from my Android app:

javax.net.ssl.SSLException: Not trusted server certificate

Here is my code:

HttpParams myParams = new BasicHttpParams();
HttpProtocolParams.setVersion(myParams, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(myParams, "utf-8");
myParams.setBooleanParameter("http.protocol.expect-continue", false);


HttpConnectionParams.setConnectionTimeout(myParams, 100000); 
HttpConnectionParams.setSoTimeout(myParams, 100000);

//
KeyStore trusted;
try {  

        trusted = KeyStore.getInstance("pkcs12");
        trusted.load(null, "".toCharArray());
        SSLSocketFactory sslf = new SSLSocketFactory(trusted);
  sslf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 

  SchemeRegistry schemeRegistry = new SchemeRegistry(); 
  schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));

  schemeRegistry.register(new Scheme("https", sslf, 443));    
  ThreadSafeClientConnManager manager = new ThreadSafeClientConnManager(myParams, schemeRegistry);


  httpClient = new DefaultHttpClient(manager, myParams); 
  } catch (KeyStoreException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (NoSuchAlgorithmException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (CertificateException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (KeyManagementException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (UnrecoverableKeyException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }         
    //

    localContext = new BasicHttpContext();  

    httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2109); 

    httpPost = new HttpPost("https://...."); 
    response = null; 

    StringEntity tmp = null;         

    httpPost.setHeader("SOAPAction", "SoapActionURL"); 

    if (contentType != null) { 
        httpPost.setHeader("Content-Type", contentType); 
    } else { 
        httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded"); 
    } 

    try { 
        tmp = new StringEntity(data,"UTF-8"); 
    } catch (UnsupportedEncodingException e) { 
        Log.e("Your App Name Here", "HttpUtils : UnsupportedEncodingException : "+e); 
    } 

    httpPost.setEntity(tmp); 

    try { 

        response = httpClient.execute(httpPost,localContext); 

        if (response != null) { 
            ret = EntityUtils.toString(response.getEntity()); 
        } 
    } catch (Exception e) { 
        Log.e("Your App Name Here", "HttpUtils: " + e); 
    }  
like image 445
user342823 Avatar asked Nov 15 '22 09:11

user342823


1 Answers

KeyStore trusted;
try {  

        trusted = KeyStore.getInstance("pkcs12");
        trusted.load(null, "".toCharArray());
        SSLSocketFactory sslf = new SSLSocketFactory(trusted);

You don't have a truststore which stores the certificate of the server you're connecting to, and that server you are connecting to is not trusted. To fix this, you need to make a keystore file using Keytool (I created a BKS keystore and loaded it with SpongyCastle provider) as a truststore.

keytool -importcert -file servercert.crt -alias mykey -keystore truststore.jks -storetype BKS -providerpath bcprov-jdk15on-151.jar -provider org.bouncycastle.jce.provider.BouncyCastleProvider

Also, I used a newer version of Apache HttpClient, specifically http://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient-android/4.3.5

public KeyStore initializeTrustStore(Context context)
{
    KeyStore keyStore = null;
    try
    {
        keyStore = KeyStore.getInstance("BKS", BouncyCastleProvider.PROVIDER_NAME);
        InputStream inputStream = context.getResources().openRawResource(R.raw.truststore);
        try
        {
            keyStore.load(inputStream, "password".toCharArray());
        }
        finally
        {
            inputStream.close();
        }
    }


    KeyStore trustStore = loadTrustStore(context);
    SSLContext sslcontext = null;
    CloseableHttpClient httpclient = null;

        SSLContextBuilder sslContextBuilder = SSLContexts.custom()
            .loadTrustMaterial(trustStore, new TrustSelfSignedStrategy());
        sslcontext = sslContextBuilder.build();

        // Allow TLSv1 protocol only
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
            sslcontext, new String[] {"TLSv1"}, null,
            SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
        );
        httpclient = HttpClients
            .custom()
            .setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
            .setSSLSocketFactory(sslsf).build();
        CloseableHttpResponse response = httpclient.execute(httpUriRequest);
        try
        {
            HttpEntity entity = response.getEntity();
            //do things with response here
            if(entity != null)
            {
                entity.consumeContent();
            }
        }
        finally
        {
            response.close();
        }
like image 200
EpicPandaForce Avatar answered Jan 08 '23 18:01

EpicPandaForce