2

我知道这不是那么困难,但非常不幸的是,我从昨天开始就被困在这里并与之抗争,我已经按照这个Android 教程中的相互身份验证,在资源中放置一个密钥库并尝试通过 SSL 连接到我的服务器,但是得到以下异常

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

我已将我的sslapptruststore.pfx文件放在res/raw/sslapptruststore.pfx 并使用这段代码

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.

任何帮助表示赞赏。

4

2 回答 2

3

我已经回答了一些看起来像您的问题的问题,如下所示:

读取 Android 应用程序的 PKCS12/P12 客户端证书文件

未找到用于认证路径的 Android volley 自签名 HTTPS 信任锚

你会找到

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

getSSLSocketFactory_Certificate文件.cert

与上面的第一个链接一样,在您的项目中,您可以调用以下两种方法之一:

如果使用密钥库文件:

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

如果使用证书文件:

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

P/S:如果这些方法在非活动类中,为避免 NPE,您必须ContextActivity传递到该类(如上面第一个链接中所示)。

希望这可以帮助!

于 2015-10-06T21:32:10.517 回答
1

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

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

}
于 2015-10-15T11:22:17.830 回答