【问题标题】:AsyncHttpClient with SSL protocol [duplicate]具有 SSL 协议的 AsyncHttpClient [重复]
【发布时间】:2014-02-26 15:20:32
【问题描述】:

我正在尝试创建我的第一个 Android 应用,但遇到了问题。

我有使用 https 协议的网络服务,从我使用 AsyncHttpClient 库的服务器获取数据,

它一直在使用 http,但是一旦我将其更改为 https,它就会给我一个错误:

No peer certificate

我在网上做了一些研究,我找到了一些如何修复它的建议,但我有能力让它发挥作用。

这只是我尝试的一些链接: link 1 link 2

我调用网络服务的代码:

    AsyncHttpClient client = new AsyncHttpClient();

    client.get(QUERY_URL,
    new JsonHttpResponseHandler() {

            @Override
            public void onSuccess(JSONObject jsonObject) {

                Log.d("test", jsonObject.toString());
            }

            @Override
            public void onFailure(int statusCode, Throwable throwable, JSONObject error) {

                Log.e("test", "Error: " + statusCode + " " + throwable.getMessage());
            }
        });

也许您推荐其他一些用于调用 https 异步的库?

【问题讨论】:

    标签: java android android-async-http


    【解决方案1】:

    这是我用于 SSL 网络的代码:

    private class MobHawkCheck extends AsyncTask<String, Void, JSONObject> {
    
            protected JSONObject doInBackground(String... params) {
                JSONObject json = null;
                try {
                    // Load CAs from an InputStream
                    // (could be from a resource or ByteArrayInputStream or ...)
                    CertificateFactory cf = CertificateFactory.getInstance("X.509");
                    // From https://www.washington.edu/itconnect/security/ca/load-der.crt
                    InputStream cert = mActivity.getResources().openRawResource(R.raw.mycertificate);
                    InputStream caInput = new BufferedInputStream(cert);
                    Certificate ca;
                    try {
                        ca = cf.generateCertificate(caInput);
                        System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
                    } finally {
                        caInput.close();
                    }
                    // Create a KeyStore containing our trusted CAs
                    String keyStoreType = KeyStore.getDefaultType();
                    KeyStore keyStore = KeyStore.getInstance(keyStoreType);
                    keyStore.load(null, null);
                    keyStore.setCertificateEntry("ca", ca);
    
                    // Create a TrustManager that trusts the CAs in our KeyStore
                    String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
                    TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
                    tmf.init(keyStore);
    
                    // Create an SSLContext that uses our TrustManager
                    SSLContext context = SSLContext.getInstance("TLS");
                    context.init(null, tmf.getTrustManagers(), null);
    
                    // Tell the URLConnection to use a SocketFactory from our SSLContext
                    URL url = new URL("https://mysecureurl.com");
                    HttpsURLConnection urlConnection =
                            (HttpsURLConnection)url.openConnection();
                    urlConnection.setSSLSocketFactory(context.getSocketFactory());
    
                    BufferedReader r = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
                    StringBuilder total = new StringBuilder();
                    String line;
                    while ((line = r.readLine()) != null) {
                        total.append(line);
                    }
                    json = new JSONObject(total.toString());
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (JSONException e) {
                    e.printStackTrace();
                } catch (KeyManagementException e) {
                    e.printStackTrace();
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (KeyStoreException e) {
                    e.printStackTrace();
                } catch (CertificateException e) {
                    e.printStackTrace();
                }
                return json;
            }
    
            protected void onPostExecute(JSONObject result) {
                //TODO parse the result JSONObject
            }
        }
    

    请注意,我使用的是自己的 .crt 文件。您应该使用服务器证书的数据生成您的证书。

    【讨论】:

    • 您可以添加示例如何调用此类吗?如果我无法访问服务器,我只是调用服务器,您知道如何获取证书文件(.crt)吗?
    • @Greg 您可以按照这个问题轻松做到这一点superuser.com/questions/97201/… 第二个答案应该是正确的,因为您无权访问服务器。我像其他任何 AsyncTask 一样调用该函数 new MobHawkCheck().execute();
    • 我尝试了你的解决方案,但我有一个错误,这只是其中的一部分: FATAL EXCEPTION: AsyncTask #1 An error occurred while execution doInBackground() Can't create handler inside thread that has not called Looper.prepare()
    • 那是因为在我的代码中,我从服务器解析结果,然后在 postExecute 上向处理程序发送一条消息。只需将其删除并按您的方式解析即可。
    • 在 onPostExecute 我注释掉了你的代码,现在只有 Lod.d("test", result);行,运行代码后出现此错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-10
    • 1970-01-01
    • 2010-12-28
    • 1970-01-01
    • 2016-02-01
    • 2018-06-21
    • 2015-11-27
    相关资源
    最近更新 更多