If you need to use a self signed certificate for your Android application using the framevork Volley and you receive exceptions like
- java.security.cert.CertPathValidatorException: Trust anchor for certification path not found
- javax.net.ssl.SSLPeerUnverifiedException: Hostname [hostname] not verified
you need to configure a TrustManager and a custom HostnameVerifier. The following code is a working Activity that implement the main configuration of the two.
First you need to put your self signed certificate in the folder res/raw es. res/raw/server.crt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.VolleyError; import com.android.volley.toolbox.HurlStack; import com.android.volley.toolbox.StringRequest; import com.android.volley.toolbox.Volley; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManagerFactory; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); RequestQueue rq = Volley.newRequestQueue(this, new HurlStack(null, getSocketFactory())); StringRequest s = new StringRequest(Request.Method.GET, "https://192.168.1.10:443", new Response.Listener<String>() { @Override public void onResponse(String s) { Log.e("RESULT",s); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { Log.e("RESULTfailder",volleyError.getMessage()); } } ); rq.add(s); } private SSLSocketFactory getSocketFactory() { CertificateFactory cf = null; try { cf = CertificateFactory.getInstance("X.509"); InputStream caInput = getResources().openRawResource(R.raw.server); Certificate ca; try { ca = cf.generateCertificate(caInput); Log.e("CERT", "ca=" + ((X509Certificate) ca).getSubjectDN()); } finally { caInput.close(); } String keyStoreType = KeyStore.getDefaultType(); KeyStore keyStore = KeyStore.getInstance(keyStoreType); keyStore.load(null, null); keyStore.setCertificateEntry("ca", ca); String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); tmf.init(keyStore); HostnameVerifier hostnameVerifier = new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { Log.e("CipherUsed", session.getCipherSuite()); return hostname.compareTo("192.168.1.10")==0; //The Hostname of your server } }; HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier); SSLContext context = null; context = SSLContext.getInstance("TLS"); context.init(null, tmf.getTrustManagers(), null); HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory()); SSLSocketFactory sf = context.getSocketFactory(); return sf; } catch (CertificateException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyStoreException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); } return null; } } |