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);
}
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();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With