Android to server communication using SSL with Bouncy Castle

前端 未结 2 1052
感动是毒
感动是毒 2020-12-06 08:59

I understand this is something which is not so difficult but very unfortunately I am stuck here and fighting it since yesterday, I have followed this Mutual Authentication i

相关标签:
2条回答
  • 2020-12-06 09:14

    I have answered some questions look like your issue as the following:

    Read in PKCS12/P12 Client Cert file for Android App

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

    You will find

        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();
        }
    

    and getSSLSocketFactory_Certificate for .cert file.

    As in the first link above, in your project you can call one of the two methods:

    If using keystore file:

    SSLSocketFactory sslSocketFactory = getSSLSocketFactory_KeyStore("PKCS12", R.raw.androidpkcs12, "123456789");
    

    If using certificate file:

    SSLSocketFactory sslSocketFactory = getSSLSocketFactory_Certificate("PKCS12", R.raw.androidpkcs12_cert);
    

    P/S: If these methods are inside a non-activity class, to avoid NPE, you must pass Context from your Activity to that class (as inside the first link above).

    Hope this helps!

    0 讨论(0)
  • 2020-12-06 09:29

    I have added the following class to solve the issue

    import org.apache.http.conn.ssl.SSLSocketFactory;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.Socket;
    import java.security.KeyManagementException;
    import java.security.KeyStore;
    import java.security.KeyStoreException;
    import java.security.NoSuchAlgorithmException;
    import java.security.UnrecoverableKeyException;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import java.util.ArrayList;
    import java.util.Arrays;
    
    import javax.net.ssl.KeyManager;
    import javax.net.ssl.KeyManagerFactory;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.TrustManagerFactory;
    import javax.net.ssl.X509TrustManager;
    
    /**
     * Allows you to trust certificates from additional KeyStores in addition to
     * the default KeyStore
     */
    public class AdditionalKeyStoresSSLSocketFactory extends SSLSocketFactory{
        protected SSLContext sslContext = SSLContext.getInstance("TLSv1");
    
        public AdditionalKeyStoresSSLSocketFactory(KeyStore keyStore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
            super(null, null, null, null, null, null);
            KeyManagerFactory keyManagerFactory = KeyManagerFactory
                    .getInstance(KeyManagerFactory.getDefaultAlgorithm());;
            keyManagerFactory.init(keyStore, "123456".toCharArray());
            sslContext.init(keyManagerFactory.getKeyManagers(), new TrustManager[]{new AdditionalKeyStoresTrustManager(keyStore)}, null);
        }
    
        @Override
        public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
            return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
        }
    
        @Override
        public Socket createSocket() throws IOException {
            return sslContext.getSocketFactory().createSocket();
        }
    
    
    
        /**
         * Based on http://download.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#X509TrustManager
         */
        public static class AdditionalKeyStoresTrustManager implements X509TrustManager {
    
            protected ArrayList<X509TrustManager> x509TrustManagers = new ArrayList<X509TrustManager>();
    
    
            protected AdditionalKeyStoresTrustManager(KeyStore... additionalkeyStores) {
                final ArrayList<TrustManagerFactory> factories = new ArrayList<TrustManagerFactory>();
    
                try {
                    // The default Trustmanager with default keystore
                    final TrustManagerFactory original = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                    original.init((KeyStore) null);
                    factories.add(original);
    
                    for( KeyStore keyStore : additionalkeyStores ) {
                        final TrustManagerFactory additionalCerts = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                        additionalCerts.init(keyStore);
                        factories.add(additionalCerts);
                    }
    
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
    
    
    
                /*
                 * Iterate over the returned trustmanagers, and hold on
                 * to any that are X509TrustManagers
                 */
                for (TrustManagerFactory tmf : factories)
                    for( TrustManager tm : tmf.getTrustManagers() )
                        if (tm instanceof X509TrustManager)
                            x509TrustManagers.add( (X509TrustManager)tm );
    
    
                if( x509TrustManagers.size()==0 )
                    throw new RuntimeException("Couldn't find any X509TrustManagers");
    
            }
    
            /*
             * Delegate to the default trust manager.
             */
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                final X509TrustManager defaultX509TrustManager = x509TrustManagers.get(0);
                defaultX509TrustManager.checkClientTrusted(chain, authType);
            }
    
            /*
             * Loop over the trustmanagers until we find one that accepts our server
             */
            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                for( X509TrustManager tm : x509TrustManagers ) {
                    try {
                        tm.checkServerTrusted(chain,authType);
                        return;
                    } catch( CertificateException e ) {
                        // ignore
                    }
                }
                throw new CertificateException();
            }
    
            public X509Certificate[] getAcceptedIssuers() {
                final ArrayList<X509Certificate> list = new ArrayList<X509Certificate>();
                for( X509TrustManager tm : x509TrustManagers )
                    list.addAll(Arrays.asList(tm.getAcceptedIssuers()));
                return list.toArray(new X509Certificate[list.size()]);
            }
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题