Android volley self signed HTTPS trust anchor for certification path not found
Asked Answered
U

1

3

I'm an android newbie. This question has been asked many times, but I've went through almost all the questions in here.

I'm trying to use a self-signed certificate on Node.Js server (using express) and Volley on android.
Using : http://blog.applegrew.com/2015/04/using-pinned-self-signed-ssl-certificate-with-android-volley/

I can't use http://ogrelab.ikratko.com/using-android-volley-with-self-signed-certificate/ because there's too much code to change on my app.

That's the error.

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

My volleysingelton code :

private SSLSocketFactory newSslSocketFactory() {
    try {
        // Get an instance of the Bouncy Castle KeyStore format
        KeyStore trusted = KeyStore.getInstance("BKS");
        // Get the raw resource, which contains the keystore with
        // your trusted certificates (root and any intermediate certs)
        InputStream in = mCtx.getResources().openRawResource(R.raw.evennewer);
        try {
            // Initialize the keystore with the provided trusted certificates
            // Provide the password of the keystore
            trusted.load(in, KEYSTORE_PASSWORD);
        } finally {
            in.close();
        }

        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(trusted);

        SSLContext context = SSLContext.getInstance("TLS");
        context.init(null, tmf.getTrustManagers(), null);

        SSLSocketFactory sf = context.getSocketFactory();
        return sf;
    } catch (Exception e) {
        throw new AssertionError(e);
    }
}

My Node.Js code :

var config     = {
  key: fs.readFileSync('./ssl/newkey.key'),
 cert: fs.readFileSync('./ssl/newcert.crt')
};
var port = 443;
var server = https.createServer(config, app).listen(port, function(){
console.log("Express server listening on port " + port);
});

And openssl debug returned:

Verify return code: 18 (self signed certificate)

Unremitting answered 22/8, 2015 at 8:38 Comment(0)
U
4

You can try the following sample code. Hope this helps!

private TrustManager[] getWrappedTrustManagers(TrustManager[] trustManagers) {
    final X509TrustManager originalTrustManager = (X509TrustManager) trustManagers[0];
    return new TrustManager[]{
            new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return originalTrustManager.getAcceptedIssuers();
                }

                public void checkClientTrusted(X509Certificate[] certs, String authType) {
                    try {
                        if (certs != null && certs.length > 0){
                            certs[0].checkValidity();
                        } else {
                            originalTrustManager.checkClientTrusted(certs, authType);
                        }
                    } catch (CertificateException e) {
                        Log.w("checkClientTrusted", e.toString());
                    }
                }

                public void checkServerTrusted(X509Certificate[] certs, String authType) {
                    try {
                        if (certs != null && certs.length > 0){
                            certs[0].checkValidity();
                        } else {
                            originalTrustManager.checkServerTrusted(certs, authType);
                        }
                    } catch (CertificateException e) {
                        Log.w("checkServerTrusted", e.toString());
                    }
                }
            }
    };
}    

private SSLSocketFactory getSSLSocketFactory_Certificate(String keyStoreType, int keystoreResId)
        throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, KeyManagementException {

    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    InputStream caInput = getResources().openRawResource(keystoreResId);

    Certificate ca = cf.generateCertificate(caInput);
    caInput.close();

    if (keyStoreType == null || keyStoreType.length() == 0) {
        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);

    TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers());

    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, wrappedTrustManagers, null);

    return sslContext.getSocketFactory();
}

private SSLSocketFactory getSSLSocketFactory_KeyStore(String keyStoreType, int keystoreResId, String keyPassword)
            throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException, KeyManagementException {

        InputStream caInput = getResources().openRawResource(keystoreResId);

        // creating a KeyStore containing trusted CAs

        if (keyStoreType == null || keyStoreType.length() == 0) {
            keyStoreType = KeyStore.getDefaultType();
        }
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);

        keyStore.load(caInput, keyPassword.toCharArray());

        // creating a TrustManager that trusts the CAs in the KeyStore

        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keyStore);

        TrustManager[] wrappedTrustManagers = getWrappedTrustManagers(tmf.getTrustManagers());

        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, wrappedTrustManagers, null);

        return sslContext.getSocketFactory();
    }

Then call one of the two:

SSLSocketFactory sslSocketFactory = getSSLSocketFactory_KeyStore("BKS", R.raw.androidbksv1, "123456789");
SSLSocketFactory sslSocketFactory = getSSLSocketFactory_Certificate("BKS", R.raw.androidbksv1_cert);
Untouched answered 26/8, 2015 at 6:12 Comment(9)
@AjayShrestha Pls wait, I'll post an answer in your question soon. Now I am online on mobile phone :-)Untouched
@Untouched Can you show us how to use this in conjunction with Volley? Thanks!Misshapen
@Misshapen I have had an answer at #32674068. Please check if it can help or notUntouched
@Untouched how to implement in volley?Rhinoplasty
I got an error only some times . And how to create certificate file which are put in raw folder?Rhinoplasty
@BhavinPatel please search more in SO, many topics available, for example, #10176312 and #2356068 and so onUntouched
@Untouched Can u tell me why i get this error ( javax.net.ssl.SSLException: SSL handshake aborted: ) only Sometime?Rhinoplasty
@BhavinPatel sorry I cannot help now, however I think you will find some useful help at #20741905Untouched
Let us continue this discussion in chat.Rhinoplasty

© 2022 - 2024 — McMap. All rights reserved.