I develop android application which uses Volley. All communication is done via HTTPS connection. Because I test it on local environment, I use self-signed certificates for Tomcat.
Before, I had only android 2.3 and 3.0 devices. Now I've got also 4.1 and 4.4.
My implementation uses this approach: http://developer.android.com/training/articles/security-ssl.html (part Unknown certificate authority) On devices with Android up to 4.1 it works perfectly. SSLSocketFactory with custom certificates is passed to Volley:
Volley.newRequestQueue(getApplicationContext(), new HurlStack(null, socketFactory));
But what happens on Android 4.1+? Why it does not work? I tried also with NullX509TrustManager like this:
private static class NullX509TrustManager implements X509TrustManager {
    @Override
    public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType)
            throws CertificateException {
    }
    @Override
    public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType)
            throws CertificateException {
    }
    @Override
    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
        return null;
    }
}
But it still does not work...
Import the self-signed certificate to the client Windows computer. On the Windows computer, start MMC (mmc.exe). Add the Certificates snap-in for the computer account and manage certificates for the local computer. Import the self-signed certificate into Trusted Root Certification Authorities > Certificates.
Go to Settings / Security / Credential storage and select “Install from device storage”. The . crt file will be detected and you will be prompted to enter a certificate name. After importing the certificate, you will find it in Settings / Security / Credential storage / Trusted credentials / User.
Right-click on the certificate you want to backup and select ALL TASKS > Import. Follow the certificate import wizard to import your primary certificate from the . pfx file. When prompted, choose to automatically place the certificates in the certificate stores based on the type of the certificate.
Trust all SSL certificates:- You can bypass SSL if you want to test on the testing server. But do not use this code for production.
public static class NukeSSLCerts {
protected static final String TAG = "NukeSSLCerts";
public static void nuke() {
    try {
        TrustManager[] trustAllCerts = new TrustManager[] { 
            new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    X509Certificate[] myTrustedAnchors = new X509Certificate[0];  
                    return myTrustedAnchors;
                }
                @Override
                public void checkClientTrusted(X509Certificate[] certs, String authType) {}
                @Override
                public void checkServerTrusted(X509Certificate[] certs, String authType) {}
            }
        };
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }
        });
    } catch (Exception e) { 
    }
}
}
Please call this function in onCreate() function in Activity or in your Application Class.
NukeSSLCerts.nuke();
This can be used for Volley in Android. More Ref. https://newfivefour.com/android-trust-all-ssl-certificates.html
I've resolved it with solution mentioned here:
http://developer.android.com/training/articles/security-ssl.html
Common Problems with Hostname Verification
by adding custom hostname verifier which returns true for my hostname in Volley project and editing HurlStack openConnection method:
if ("https".equals(url.getProtocol()) && mSslSocketFactory != null) {            
    ((HttpsURLConnection)connection).setSSLSocketFactory(mSslSocketFactory);
    ((HttpsURLConnection)connection).setHostnameVerifier(new CustomHostnameVerifier());         
}
If you already have a .crt file and looking to get it attached to Volley then here are 2 simple steps to follow.
Step 1: Write this method to your code.
public SSLSocketFactory getSocketFactory(Context context)
        throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
    // Load CAs from an InputStream (could be from a resource or ByteArrayInputStream or ...)
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    InputStream caInput = new BufferedInputStream(context.getResources().openRawResource(R.raw.myFile));
                                                   // I paste my myFile.crt in raw folder under res.
    Certificate ca;
    //noinspection TryFinallyCanBeTryWithResources
    try {
        ca = cf.generateCertificate(caInput);
        System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
    } finally {
        caInput.close();
    }
    // Create a KeyStore containing our trusted CAs
    String keyStoreType = KeyStore.getDefaultType();
    KeyStore keyStore = KeyStore.getInstance(keyStoreType);
    keyStore.load(null, null);
    keyStore.setCertificateEntry("ca", ca);
    // Create a TrustManager that trusts the CAs in our KeyStore
    String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
    tmf.init(keyStore);
    // Create an SSLContext that uses our TrustManager
    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, tmf.getTrustManagers(), null);
    return sslContext.getSocketFactory();
}
Step 2: Just add this below line before you make any request using Volley.
HttpsURLConnection.setDefaultSSLSocketFactory(getSocketFactory(context));
Android Studio will ask you to enclose that line in try/catch for all Exceptions thrown by our method. So just let it do that.
Happy Coding!
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