【问题标题】:Getting javax.net.ssl.SSLException: Not trusted server certificate in Android获取 javax.net.ssl.SSLException:Android 中不受信任的服务器证书
【发布时间】:2012-06-23 16:56:44
【问题描述】:

我正在使用以下代码对 http 链接进行 SOAP 请求

private String SOAPServiceCall(String url, String envelopeString) {


    final DefaultHttpClient httpClient = new DefaultHttpClient();
    // request parameters
    HttpParams params = httpClient.getParams();
    HttpConnectionParams.setConnectionTimeout(params, 50000);
    HttpConnectionParams.setSoTimeout(params, 55000);
    // set parameter
    HttpProtocolParams.setUseExpectContinue(httpClient.getParams(), true);

    // POST the envelope
    HttpPost httppost = new HttpPost(url);
    // add headers
    // httppost.setHeader("soapaction", soapAction);
    httppost.setHeader("Content-Type", "text/xml; charset=utf-8");

    String responseString = "";
    try {

        HttpEntity entity = new StringEntity(envelopeString);
        httppost.setEntity(entity);

        // Response handler
        ResponseHandler<String> rh = new ResponseHandler<String>() {
            // invoked when client receives response
            public String handleResponse(HttpResponse response)
                    throws ClientProtocolException, IOException {

                // get response entity
                HttpEntity entity = response.getEntity();

                // read the response as byte array
                StringBuffer out = new StringBuffer();
                byte[] b = EntityUtils.toByteArray(entity);

                // write the response byte array to a string buffer
                out.append(new String(b, 0, b.length));
                return out.toString();
            }
        };

        responseString = httpClient.execute(httppost, rh);

    } catch (Exception e) {
        e.printStackTrace();
    }

    // close the connection
    httpClient.getConnectionManager().shutdown();

    return responseString;

}

一切正常。但是现在我的客户端已经从http变成了https,所以我使用了如下代码:

private String SOAPServiceCall(String url, String envelopeString) {


    StringBuffer buffer = null;
    try {
        URL address=new URL(url);
        URLConnection connection=address.openConnection();
        HttpsURLConnection post=(HttpsURLConnection)connection;
        post.setDoInput(true);
        post.setDoOutput(true);
        post.setRequestMethod("POST");
        //post.setRequestProperty("SOAPAction", soapAction);
        post.setRequestProperty( "Content-type", "text/xml; charset=utf-8" );
        post.setRequestProperty( "Content-Length", String.valueOf(envelopeString.length()));
        post.setReadTimeout(4000);

        OutputStream outStream=post.getOutputStream();
        Writer out=new OutputStreamWriter(outStream);
        out.write(envelopeString);
        out.flush();
        out.close();

        InputStream inStream = post.getInputStream();
        BufferedInputStream in = new BufferedInputStream(inStream,4);
        buffer = new StringBuffer();
        // read 4 bytes a time
        byte[] buffArray=new byte[4];
        int c=0;
            while((c=in.read(buffArray))!=-1){
                for(int i=0;i<c;i++)
                    buffer.append((char)buffArray[i]);
            }

    return buffer.toString();
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (ProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return null;
}

我正在使用来自this link 的代码。

现在我得到了:

06-23 17:30:26.879: W/System.err(2168): javax.net.ssl.SSLException: Not trusted server certificate
06-23 17:30:26.889: W/System.err(2168):     at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:371)
06-23 17:30:26.889: W/System.err(2168):     at org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection.getSecureSocket(HttpConnection.java:168)
06-23 17:30:26.899: W/System.err(2168):     at org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:399)
06-23 17:30:26.899: W/System.err(2168):     at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.sendRequest(HttpURLConnectionImpl.java:1325)
06-23 17:30:26.909: W/System.err(2168):     at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.doRequestInternal(HttpURLConnectionImpl.java:1656)
06-23 17:30:26.909: W/System.err(2168):     at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.doRequest(HttpURLConnectionImpl.java:1649)
06-23 17:30:26.909: W/System.err(2168):     at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:1248)
06-23 17:30:26.919: W/System.err(2168):     at org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:263)
06-23 17:30:26.919: W/System.err(2168):     at org.apis.SOAPRequest.SOAPServiceCall(SOAPRequest.java:184)
06-23 17:30:26.929: W/System.err(2168):     at org.apis.SOAPRequest.retrieveSessionId(SOAPRequest.java:125)
06-23 17:30:26.929: W/System.err(2168):     at org.activity.LoginPage$FetchSessionIDTask.doInBackground(LoginPage.java:76)
06-23 17:30:26.929: W/System.err(2168):     at org.activity.LoginPage$FetchSessionIDTask.doInBackground(LoginPage.java:1)
06-23 17:30:26.929: W/System.err(2168):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
06-23 17:30:26.929: W/System.err(2168):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
06-23 17:30:26.929: W/System.err(2168):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
06-23 17:30:26.929: W/System.err(2168):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
06-23 17:30:26.929: W/System.err(2168):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
06-23 17:30:26.939: W/System.err(2168):     at java.lang.Thread.run(Thread.java:1102)
06-23 17:30:26.939: W/System.err(2168): Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: TrustAnchor for CertPath not found.
06-23 17:30:26.939: W/System.err(2168):     at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:168)
06-23 17:30:26.939: W/System.err(2168):     at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:366)
06-23 17:30:26.939: W/System.err(2168):     ... 17 more
06-23 17:30:26.939: W/System.err(2168): Caused by: java.security.cert.CertPathValidatorException: TrustAnchor for CertPath not found.
06-23 17:30:26.949: W/System.err(2168):     at org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi.engineValidate(PKIXCertPathValidatorSpi.java:149)
06-23 17:30:26.949: W/System.err(2168):     at java.security.cert.CertPathValidator.validate(CertPathValidator.java:202)
06-23 17:30:26.949: W/System.err(2168):     at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:164)
06-23 17:30:26.949: W/System.err(2168):     ... 18 more

所以我用谷歌搜索并找到了这些链接:

link 1
link 2
link 3
link 4
link 5
link 6
link 7(好一个..但不适合初学者)
link 8
link 9
link 10

还有更多。

但我无法解决此问题;我现在对此感到非常困惑,我不知道从哪里开始,哪种方法是正确的。

我没有尝试按键方法,因为它需要一些证书,我不知道它是什么。我从异常中发现它正在寻找一些受信任的证书

我应该从哪里开始,采取什么方法,该证书是什么,我将如何下载它等等?

【问题讨论】:

    标签: android exception https ssl-certificate


    【解决方案1】:

    让我知道这是否适合你.. 在你的 SOAPServiceCall() 方法中添加这个,

    trustAllHosts();
     HttpsURLConnection post = (HttpsURLConnection) url.openConnection();
     https.setHostnameVerifier(DO_NOT_VERIFY);
    
    
    and add these methods,
    // always verify the host - dont check for certificate
    final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                    return true;
            }
    };
    
    /**
     * Trust every server - dont check for any certificate
     */
    private static void trustAllHosts() {
            // Create a trust manager that does not validate certificate chains
            TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return new java.security.cert.X509Certificate[] {};
                    }
    
                    public void checkClientTrusted(X509Certificate[] chain,
                                    String authType) throws CertificateException {
                    }
    
                    public void checkServerTrusted(X509Certificate[] chain,
                                    String authType) throws CertificateException {
                    }
            } };
    
            // Install the all-trusting trust manager
            try {
                    SSLContext sc = SSLContext.getInstance("TLS");
                    sc.init(null, trustAllCerts, new java.security.SecureRandom());
                    HttpsURLConnection
                                    .setDefaultSSLSocketFactory(sc.getSocketFactory());
            } catch (Exception e) {
                    e.printStackTrace();
            }
    }
    

    参考:http://stackoverflow.com/questions/995514/https-connection-android#1000205

    【讨论】:

      猜你喜欢
      • 2020-11-14
      • 2011-08-01
      • 1970-01-01
      • 2014-11-29
      • 1970-01-01
      • 1970-01-01
      • 2012-02-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多