1. 程式人生 > >okHttp訪問Https-----信任當前證書和所有證書

okHttp訪問Https-----信任當前證書和所有證書

/*
* 第一種方式:只信任當前的證書*    1.android客戶端從伺服器下載https證書,放到專案的assets檔案下     2.okhttp的固定程式碼,進行https各種配置,比如X.509,固定的模式,直接拷貝     3.設定證書,assets檔案下,按照證書的名稱讀取設定給okhttp
所以一般我們會把2,3兩部封裝成一個方法,暴露一個String引數,複製輸入證書的名稱,然後直接呼叫即可     4.接下來就是初級call物件,非同步請求,okhttp的正常使用一樣
  第二種方式:信任所有https主機的訪問         1.OkHttpClient初始化時,
配置建立一個證書物件,校驗名稱,信任所有的主機,也就是信任所有https的請求 對應所要建立的類,是固定模式,直接拷貝使用即可 2.okhttp的正常使用 兩種方式要想看效果,需要新增okhttp的日誌攔截器方可 提示: 1.信任所有的伺服器地址,所有的https網址,我們去請求資料時,都會返回的有資料. 大部分公司沒有去弄證書,偷懶所以就信任所有的伺服器地址,這樣合法性保證不了,但是資料加密沒有問題. 2.信任自己的伺服器,載入自己的證書時,只有我們自己的伺服器才會返回有資料,其他https網址就壓根不會連線 這樣做最穩妥,
下載自己的證書.校驗本地證書. 伺服器通過命令列的模式生成一個證書(java的工具類生成),然後伺服器配置這個證書,支援https,埠號443. 注意:使用日誌攔截器,要看看模擬有沒有SD卡裝置,4.1.1 * */
 @Override
protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
    //只信任當前證書
certData();
     //信任所有證書
loadData();

  }
   /*
* 信任所有證書的方法 * */ private void loadData() { OkHttpClient httpClient = new OkHttpClient.Builder() .addInterceptor(new LogInterceptor())//新增okhttp日誌攔截器 //不加以下兩行程式碼,https請求不到自簽名的伺服器 .sslSocketFactory(createSSLSocketFactory())//建立一個證書物件 .hostnameVerifier(new TrustAllHostnameVerifier())//校驗名稱,這個物件就是信任所有的主機,也就是信任所有https的請求 .connectTimeout(10, TimeUnit.SECONDS)//連線超時時間 .readTimeout(10, TimeUnit.SECONDS)//讀取超時時間 .writeTimeout(10, TimeUnit.SECONDS)//寫入超時時間 .retryOnConnectionFailure(false)//連線不上是否重連,false不重連 .build(); //提交表單,輸入的賬戶名和密碼按照伺服器定義的格式 FormBody formbody = new FormBody.Builder().add("mobile", "18612991023").add("password", "111111").build(); Request request = new Request.Builder().url("https://www.zhaoapi.cn/user/login").post(formbody).build(); httpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(okhttp3.Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { Log.d("++=====++++",""+response.body().string()); } }); } private static SSLSocketFactory createSSLSocketFactory() { SSLSocketFactory ssfFactory = null; try { SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, new TrustManager[]{new TrustAllCerts()}, new SecureRandom()); ssfFactory = sc.getSocketFactory(); } catch (Exception e) { } return ssfFactory; } private static class TrustAllCerts implements X509TrustManager { @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } } //信任所有的伺服器,返回true private static class TrustAllHostnameVerifier implements HostnameVerifier { @Override public boolean verify(String hostname, SSLSession session) { return true; } } /* * 信任當前證書的方法* */ private void certData() { //提交表單資訊 FormBody formbody = new FormBody.Builder() .add("mobile", "18612991023") .add("password", "111111") .build(); //請求物件初始化的設定,請求Url,請求方式,表單資訊 Request request = new Request.Builder().url("https://www.zhaoapi.cn/user/login").post(formbody).build(); //setCard(),用時直接拷貝,app帶證書驗證 setCard("zhaoapi_server.cer").newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { Log.d("+++++++",""+response.body().string()); } }); } /** * app帶證書驗證的方法,使用是修改一下zhaoapi_server.cer即可,其他都是固定的模式,直接拷貝 */ public OkHttpClient setCard(String zhenshu) { OkHttpClient.Builder builder = new OkHttpClient.Builder(); try { //https固定模式,X.509是固定的模式 CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); //關聯證書的物件 KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null); String certificateAlias = Integer.toString(0); //核心邏輯,信任什麼證書,Assets讀取拷貝進去的證書 keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(getAssets().open(zhenshu))); SSLContext sslContext = SSLContext.getInstance("TLS"); //信任關聯器 final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); //初始化證書物件 trustManagerFactory.init(keyStore); sslContext.init ( null, trustManagerFactory.getTrustManagers(), new SecureRandom() ); builder.sslSocketFactory(sslContext.getSocketFactory()); builder.addInterceptor(new LogInterceptor()); builder.hostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String s, SSLSession sslSession) { return true; } }); } catch (Exception e) { e.printStackTrace(); } return builder.build(); }