使用SSL与Bouncy Castle进行Android到服务器通信 [英] Android to server communication using SSL with Bouncy Castle

查看:265
本文介绍了使用SSL与Bouncy Castle进行Android到服务器通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这不是那么困难但不幸的是我从昨天起就被困在这里并且打了它,我跟着这个 Android中的相互身份验证教程,将密钥库置于资源中并尝试通过SSL连接到我的服务器,但得到以下异常

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 in Android tutorial, to place a keystore in resources and trying to connect to my server over SSL, but getting the following exception


java.lang.RuntimeException:
org.spongycastle.jcajce .provider.asymmetric.x509.CertificateFactory $ ExCertificateException

java.lang.RuntimeException: org.spongycastle.jcajce.provider.asymmetric.x509.CertificateFactory$ExCertificateException

我已经放置了我的 sslapptruststore.pfx 文件 res / raw / sslapptruststore.pfx
并使用这段代码

I have placed my sslapptruststore.pfx file under res/raw/sslapptruststore.pfx and using this piece of code

try {

                           KeyStore clientCert = KeyStore.getInstance("PKCS12");
                                   clientCert.load(getResources().openRawResource(R.raw.sslapptruststore), "123456".toCharArray());// this line causes exception

                            HttpClient httpClient = null;
                            HttpParams httpParams = new BasicHttpParams();
                            SSLSocketFactory sslSocketFactory = new SSLSocketFactory(clientCert, null, null);
                            SchemeRegistry registry = new SchemeRegistry();
                            registry.register(new Scheme("https", sslSocketFactory, 8443));
                            httpClient = new DefaultHttpClient(new ThreadSafeClientConnManager(httpParams, registry), httpParams);


                            HttpPost httpPost = new HttpPost(
                                    "https://192.168.1.113:8443/CertProvider");
                            httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
                            List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(2);
                            nameValuePair.add(new BasicNameValuePair("csr", csr.toString()));

                            // Url Encoding the POST parameters
                                httpPost.setEntity(new UrlEncodedFormEntity(nameValuePair));

                            // Making HTTP Request
                            // HttpResponse response = null;
                            ResponseHandler<String> responseHandler = new BasicResponseHandler();
                            String response = "";
                            response = httpClient.execute(httpPost, responseHandler);
                                } catch (Exception e) {
                                    Log.e("", e.getMessage());
                                }

我也搜索过但其他人正在使用 .bks

I have also searched but others are using .bks.

感谢任何帮助。

推荐答案

我添加了以下类来解决问题

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

}

这篇关于使用SSL与Bouncy Castle进行Android到服务器通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆