Android https与自定义证书的连接

时间:2012-12-13 11:48:42

标签: android ssl https connection httpsurlconnection

我想使用位于p12 pack中的自定义证书来建立https连接。我已经在iPhone上做过了(所以我可以验证,证书,服务器等一切都很好),但是在Android上有一些问题。

我跟随How to request a URL that requires a client certificate for authentication answear,但结果我得到以下例外:

  

12-13 12:32:44.545:W / System.err(4407):   javax.net.ssl.SSLHandshakeException:   java.security.cert.CertPathValidatorException:信任锚   未找到证书路径。 12-13 12:32:44.545:W / System.err(4407):     在   org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:374)   12-13 12:32:44.545:W / System.err(4407):at   libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:209)   12-13 12:32:44.545:W / System.err(4407):at   libcore.net.http.HttpsURLConnectionImpl $ HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:478)   12-13 12:32:44.545:W / System.err(4407):at   libcore.net.http.HttpsURLConnectionImpl $ HttpsEngine.connect(HttpsURLConnectionImpl.java:433)   12-13 12:32:44.545:W / System.err(4407):at   libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:289)   12-13 12:32:44.550:W / System.err(4407):at   libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:239)12-13   12:32:44.550:W / System.err(4407):at   libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80)   12-13 12:32:44.550:W / System.err(4407):at   libcore.net.http.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:165)   12-13 12:32:44.550:W / System.err(4407):at   com.geckolab.httptestandroid.MainActivity.downloadUrlHttps(MainActivity.java:172)   12-13 12:32:44.550:W / System.err(4407):at   com.geckolab.httptestandroid.MainActivity.access $ 0(MainActivity.java:151)   12-13 12:32:44.550:W / System.err(4407):at   com.geckolab.httptestandroid.MainActivity $ DownloadWebPageTextHttps.doInBackground(MainActivity.java:99)   12-13 12:32:44.550:W / System.err(4407):at   com.geckolab.httptestandroid.MainActivity $ DownloadWebPageTextHttps.doInBackground(MainActivity.java:1)   12-13 12:32:44.550:W / System.err(4407):at   android.os.AsyncTask $ 2.call(AsyncTask.java:287)12-13 12:32:44.550:   W / System.err(4407):at   java.util.concurrent.FutureTask中$ Sync.innerRun(FutureTask.java:305)   12-13 12:32:44.555:W / System.err(4407):at   java.util.concurrent.FutureTask.run(FutureTask.java:137)12-13   12:32:44.555:W / System.err(4407):at   android.os.AsyncTask $ SerialExecutor $ 1.run(AsyncTask.java:230)12-13   12:32:44.555:W / System.err(4407):at   java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)   12-13 12:32:44.555:W / System.err(4407):at   java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:569)   12-13 12:32:44.555:W / System.err(4407):at   java.lang.Thread.run(Thread.java:856)12-13 12:32:44.555:   W / System.err(4407):引起:   java.security.cert.CertificateException:   java.security.cert.CertPathValidatorException:信任锚   未找到证书路径。 12-13 12:32:44.560:W / System.err(4407):     在   org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:192)   12-13 12:32:44.560:W / System.err(4407):at   org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:163)   12-13 12:32:44.560:W / System.err(4407):at   org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:573)   12-13 12:32:44.560:W / System.err(4407):at   org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(母语   方法)12-13 12:32:44.560:W / System.err(4407):at   org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:371)   12-13 12:32:44.560:W / System.err(4407):... 18更多12-13   12:32:44.560:W / System.err(4407):引起:   java.security.cert.CertPathValidatorException:信任锚   未找到证书路径。 12-13 12:32:44.560:W / System.err(4407):     ......还有23个

我的连接代码如下所示:

KeyStore ks = KeyStore.getInstance("PKCS12");
        ks.load(context.getResources().openRawResource(R.raw.gecko_cert_1), "gecko_cert_1".toCharArray());
        KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
        kmf.init(ks, "gecko_cert_1".toCharArray());
        SSLContext sc = SSLContext.getInstance("TLS");
        sc.init(kmf.getKeyManagers(), null, null);


        //request
        URL serverURL = new URL(myurl); 
        HttpsURLConnection conn = (HttpsURLConnection)serverURL.openConnection();
        conn.setSSLSocketFactory(sc.getSocketFactory());
        //conn.setHostnameVerifier(DO_NOT_VERIFY);
        conn.setReadTimeout(10000 /* milliseconds */);
        conn.setConnectTimeout(15000 /* milliseconds */);
        conn.setRequestMethod("GET");
        conn.setDoInput(true);
        // Starts the query
        conn.connect();

干杯, 马尔钦

1 个答案:

答案 0 :(得分:-4)

现在对我有用。

我在连接方法的基础上添加了以下代码段:

       X509TrustManager[] tm = new X509TrustManager[] { new X509TrustManager() {
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
        } };

然后交换线:

sc.init(kmf.getKeyManagers(), null, null);

为:

sc.init(kmf.getKeyManagers(), tm, null);

我也取消注释了这一行:

conn.setHostnameVerifier(DO_NOT_VERIFY);

干杯, 马尔钦