在android的开发过程中,我们目前常用到的网络请求框架基本都是基于Okhttp,而Https网络通信在APP的开发中也被应用的越来越多,Okhttp默认是支持https网络请求的,但是支持的Https网站必须是CA机构认证了的,对于自签名的网址,还是不能访问的,访问直接抛出如下异常信息:

onFailure: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

针对https的处理,目前主要有两种方式:

  • 客户端默认信任全部证书
  • 对自签名网址进行证书的单独处理

客户端默认信任全部证书

这个方式实现起来简单,但是因为信任了全部证书,会有一定的风险!使用者需注意,下面了解一下具体的实现:

1.新建MyTrustManager实现X509TrustManager接口:

public class MyTrustManager implements X509TrustManager {    @Override    public void checkClientTrusted(X509Certificate[] chain, String authType) {}    @Override    public void checkServerTrusted(X509Certificate[] chain, String authType) {}    @Override    public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];}}

2.创建一个方法,用于获取SSLSocketFactory:

private static SSLSocketFactory createSSLSocketFactory() {        SSLSocketFactory ssfFactory = null;        try {            SSLContext sc = SSLContext.getInstance("SSL");            sc.init(null, new TrustManager[]{new MyTrustManager()}, new SecureRandom());            ssfFactory = sc.getSocketFactory();        } catch (Exception e) {            e.printStackTrace();        }        return ssfFactory;    }

3.OKhttpClient的配置:

static {     OkHttpClient.Builder builder = new OkHttpClient.Builder();     builder.connectTimeout(30, TimeUnit.SECONDS);     builder.sslSocketFactory(createSSLSocketFactory());     builder.hostnameVerifier(new HostnameVerifier() {         @Override         public boolean verify(String hostname, SSLSession session) {             return true;         }     });     mOkHttpClient = builder.build(); }

将其封装到Okhttp工具类中,完整代码如下所示:

public class OkhttpUtil {    public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");    public static final MediaType JSON2 = MediaType.parse("application/x-www-form-urlencoded; charset=utf-8");    private static OkHttpClient mOkHttpClient = new OkHttpClient();    private static SSLSocketFactory createSSLSocketFactory() {        SSLSocketFactory ssfFactory = null;        try {            SSLContext sc = SSLContext.getInstance("TLS");            sc.init(null, new TrustManager[]{new MyTrustManager()}, new SecureRandom());            ssfFactory = sc.getSocketFactory();        } catch (Exception e) {            e.printStackTrace();        }        return ssfFactory;    }    static {        OkHttpClient.Builder builder = new OkHttpClient.Builder();        builder.connectTimeout(30, TimeUnit.SECONDS);        builder.sslSocketFactory(createSSLSocketFactory());        builder.hostnameVerifier(new HostnameVerifier() {            @Override            public boolean verify(String hostname, SSLSession session) {                return true;            }        });        mOkHttpClient = builder.build();    }    public static Response execute(Request request) throws IOException {        return mOkHttpClient.newCall(request).execute();    }    public static void enqueue(Request request, Callback responseCallback) {        mOkHttpClient.newCall(request).enqueue(responseCallback);    }    public static void enqueue(Request request) {        mOkHttpClient.newCall(request).enqueue(new Callback() {            @Override            public void onFailure(Call call, IOException e) {            }            @Override            public void onResponse(Call call, Response response) throws IOException {            }        });    }    public static String getStringFromServer(String url) throws IOException {        Request request = new Request.Builder().url(url).build();        Response response = execute(request);        if (response.isSuccessful()) {            String responseUrl = response.body().string();            return responseUrl;        } else {            throw new IOException("Unexpected code " + response);        }    }    private static final String CHARSET_NAME = "UTF-8";    public static String formatParams(List params) {        return URLEncodedUtils.format(params, CHARSET_NAME);    }    public static String attachHttpGetParams(String url, List params) {        return url + "?" + formatParams(params);    }    public static String attachHttpGetParam(String url, String name, String value) {        return url + "?" + name + "=" + value;    }    public static String post(String url, FormBody body) throws IOException {        Request request = new Request.Builder()                .url(url)                .post(body)                .build();        Response response = mOkHttpClient.newCall(request).execute();        if (response.isSuccessful()) {            return response.body().string();        } else {            throw new IOException("Unexpected code " + response);        }    }    public static String post(String url, JSONObject jsonObject) throws IOException {        RequestBody body = RequestBody.create(JSON, jsonObject.toString());        Request request = new Request.Builder()                .url(url)                .post(body)                .build();        Response response = mOkHttpClient.newCall(request).execute();        if (response.isSuccessful()) {            return response.body().string();        } else {            throw new IOException("Unexpected code " + response);        }    }    public static String postFrom2Json(String url, JSONObject jsonObject) throws IOException {        RequestBody body = RequestBody.create(JSON2, jsonObject.toString());        Request request = new Request.Builder()                .url(url)                .post(body)                .build();        Response response = mOkHttpClient.newCall(request).execute();        if (response.isSuccessful()) {            return response.body().string();        } else {            throw new IOException("Unexpected code " + response);        }    }    /**     * get 方式请求  异步线程中执行     *     * @param url 请求地址     * @return 请求结果     */    public static String get(String url) throws IOException {        Request request = new Request.Builder().url(url).build();        Response response = mOkHttpClient.newCall(request).execute();        if (response.isSuccessful()) {            return response.body().string();        } else {            throw new IOException("Unexpected code " + response);        }    }    /**     * get 方式请求  异步线程中执行     *     * @param url 请求地址     * @return 请求结果     */    public static void get(String url, Callback responseCallback) {        Request request = new Request.Builder().url(url).build();        mOkHttpClient.newCall(request).enqueue(responseCallback);    }}

至此,客户端默认信任全部证书的实现方式就基本实现了。
##WebView中Https的处理
当前很多应用都使用webview加载H5页面,如果服务端采用的是可信CA颁发的证书,在 webView.setWebViewClient(webviewClient) 时重载 WebViewClient的onReceivedSslError() ,如果出现证书错误,直接调用handler.proceed()会忽略错误继续加载证书有问题的页面;如果调用handler.cancel()可以终止加载证书有问题的页面;证书出现问题了,可以提示用户风险,让用户选择加载与否,如果是需要安全级别比较高,可以直接终止页面加载,提示用户网络环境有风险。handler.proceed方法是接受所有的证书,和上文所说的一样当然也是不安全的一种方法。

@Override    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {          handler.proceed();          view.getSettings().setJavaScriptEnabled(true);     }            

对自签名网站进行处理

对自签名网站进行处理网络上有较多的介绍,这里推荐鸿洋的Https相关完全解析 当OkHttp遇到Https 文中对处理的方式有详细的介绍,本文不再做单独的说明处理。

更多相关文章

  1. Android(安卓)基本控件及表单三大控件,事件处理
  2. Android应用程序键盘(Keyboard)消息处理机制分析(1)
  3. android的Handler
  4. android静默安装的实现(一)
  5. Android学习笔记:Android消息处理机制之Handler介绍
  6. Android绘制优化----系统显示原理
  7. Android应用程序请求SurfaceFlinger服务渲染Surface的过程分析
  8. Android应用程序消息处理机制(Looper、Handler)分析
  9. 【Android(安卓)开发】: Android(安卓)消息处理机制之三: Handle

随机推荐

  1. Ubuntu 16.04 LTS 编译 Android(安卓)7.1
  2. 一步一坑学android之禁用Appt2(andriod st
  3. Android开发笔记(一百一十七)app省电方略
  4. 【实践】客户端JSBridge实现文档
  5. Android开发之非Activity类型的Context启
  6. android 4.4以上实现沉浸式状态栏
  7. Android异步通信中实现子线程的定时启动
  8. Android(安卓)TextWatcher监控EditText中
  9. [译]Kotlin中是应该使用序列(Sequences)
  10. Android(安卓)Animation之ScaleAnimation