你的位置:首页 > 软件开发 > 操作系统 > Https系列之四:https的SSL证书在Android端基于okhttp,Retrofit的使用

Https系列之四:https的SSL证书在Android端基于okhttp,Retrofit的使用

发布时间:2017-09-28 09:00:08
Https系列会在下面几篇文章中分别作介绍:一:https的简单介绍及SSL证书的生成二:https的SSL证书在服务器端的部署,基于tomcat,spring boot三:让服务器同时支持http、https,基于spring boot四:https的SSL证书在Android ...

Https系列会在下面几篇文章中分别作介绍:

一:https的简单介绍及SSL证书的生成
二:https的SSL证书在服务器端的部署,基于tomcat,spring boot
三:让服务器同时支持http、https,基于spring boot
四:https的SSL证书在Android端基于okhttp,Retrofit的使用

所有文章会优先在:
微信公众号“颜家大少”中发布
转载请标明出处


先来回顾一下

前面已分别介绍了https,SSL证书的生成,并完成了服务器端的https的部署
并提到一个重要的用于客户端的证书:公钥证书
在前面文章中,自签名SSL证书对应的公钥证书为:mycer.cer(当然这名字是自己随便定的);在阿里云申请的CA证书中对应的公钥证书为:*.pem
如果有不清楚的,请看我之前介绍过的文章

Android自带的可信任的CA公钥证书

还要说明一下,Android系统有自带的安卓认可的证书颁发机构(如:Wosign)颁发的可信任的CA公钥证书,大概有100多个,
可自己查看,各个手机的查看方法可能不一样,在我的手机中,能在下面的位置中找到:
“设置”->”更多设置“->”系统安全“->”信任的凭据”
也就是说,如果你服务器的证书是安卓认可的证书颁发机构颁发的,那么你并不需要在Android端额外安装公钥证书,否则,你就需要安装。
注:在不同版本的Android系统上,可信任的CA证书可能是不一样的,如果你担心在别人的Android系统上可能此CA证书不被信任,那你统一都安装也是没问题的
我在阿里云上申请的免费型DV SSL证书,是属于安卓认可的证书颁发机构颁发的,不需要额外安装,当然我们的自签名证书,是必需要安装的
其实我在测试的过程中,把自签名证书和阿里云上申请的免费型DV SSL证书都用同样的方法安装了,都是OK的

我们下面就开始基于okhttp来安装公钥证书了

先看看我的okhttp和retrofit的gradle版本

compile 'com.squareup.okhttp3:okhttp:3.8.1'compile 'com.squareup.retrofit2:retrofit:2.3.0'

增加一个OkhttpManager类

统一处理OkHttpClient的证书,完整的代码如下:

import android.content.Context;import java.io.IOException;import java.io.InputStream;import java.security.GeneralSecurityException;import java.security.KeyStore;import java.security.cert.Certificate;import java.security.cert.CertificateFactory;import java.util.Arrays;import java.util.Collection;import javax.net.ssl.KeyManagerFactory;import javax.net.ssl.SSLContext;import javax.net.ssl.SSLSocketFactory;import javax.net.ssl.TrustManager;import javax.net.ssl.TrustManagerFactory;import javax.net.ssl.X509TrustManager;import okhttp3.OkHttpClient;public class OkhttpManager { static private OkhttpManager mOkhttpManager=null; private InputStream mTrustrCertificate; static public OkhttpManager getInstance() {  if(mOkhttpManager==null)  {   mOkhttpManager=new OkhttpManager();  }  return mOkhttpManager; } private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException {  try {   KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());   InputStream in = null; // By convention, 'null' creates an empty key store.   keyStore.load(in, password);   return keyStore;  } catch (IOException e) {   throw new AssertionError(e);  } } private X509TrustManager trustManagerForCertificates(InputStream in)   throws GeneralSecurityException {  CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");  Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(in);  if (certificates.isEmpty()) {   throw new IllegalArgumentException("expected non-empty set of trusted certificates");  }  // Put the certificates a key store.  char[] password = "password".toCharArray(); // Any password will work.  KeyStore keyStore = newEmptyKeyStore(password);  int index = 0;  for (Certificate certificate : certificates) {   String certificateAlias = Integer.toString(index++);   keyStore.setCertificateEntry(certificateAlias, certificate);  }  // Use it to build an X509 trust manager.  KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());  keyManagerFactory.init(keyStore, password);  TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());  trustManagerFactory.init(keyStore);  TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();  if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {   throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));  }  return (X509TrustManager) trustManagers[0]; } public void setTrustrCertificates(InputStream in) {  mTrustrCertificate=in; } public InputStream getTrustrCertificates() {  return mTrustrCertificate; } public OkHttpClient build() {  OkHttpClient okHttpClient=null;  if(getTrustrCertificates()!=null)  {   X509TrustManager trustManager;   SSLSocketFactory sslSocketFactory;   try {    trustManager = trustManagerForCertificates(getTrustrCertificates());    SSLContext sslContext = SSLContext.getInstance("TLS");    sslContext.init(null, new TrustManager[] { trustManager }, null);    sslSocketFactory = sslContext.getSocketFactory();   } catch (GeneralSecurityException e) {    throw new RuntimeException(e);   }   okHttpClient=new OkHttpClient.Builder()     .sslSocketFactory(sslSocketFactory, trustManager)     .build();  }  else  {   okHttpClient=new OkHttpClient.Builder()           .build();  }  return okHttpClient; }}

代码解释

代码不少,其实最核心的代码为:

public OkHttpClient build(){....... trustManager = trustManagerForCertificates(getTrustrCertificates()); ....... okHttpClient=new OkHttpClient.Builder()     .sslSocketFactory(sslSocketFactory, trustManager)     .build(); .......... return okHttpClient;}

也就是通过

void setTrustrCertificates(InputStream in)

把自己的证书对应的文件set进去

然后通过

trustManager =trustManagerForCertificates(getTrustrCertificates());

okHttpClient=new OkHttpClient.Builder()     .sslSocketFactory(sslSocketFactory, trustManager)     .build();

就能生成安装好了可信任证书的okHttpClient

OkhttpManager说完了,接下来,就是:

Activity中使用OkhttpManager

1:先把公钥证书文件(如:自签名的mycer.cer或CA证书的:*.pem)放到assets下,
如果使用AndroidStudio的同学,可能没有assets文件夹,自己建此文件夹,如我的为:app\src\main\assets

2:直接贴Activity主要的代码:

public class MyActivity extends AppCompatActivity {@Override protected void onCreate(@Nullable Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  try {   OkhttpManager.getInstance().setTrustrCertificates(getAssets().open("mycer.cer");   OkHttpClient mOkhttpClient= OkhttpManager.getInstance().build();  } catch (IOException e) {   e.printStackTrace();  }}

简单吧,主要代码就那两句,就生成了已安装公钥证书”mycer.cer”的mOkhttpClient
接下来的mOkhttpClient怎样使用,大家都应该清楚了吧,如果不清楚只能看OkHttpClient的基础内容了

好了,OkHttpClient搞掂了

接下来就到Retrofit了

大家应该知到Retrofit默认是以OkHttpClient来作为传输的,既然OkHttpClient搞掂了,那Retrofit就简单了
还是直接贴代码:

 Retrofit retrofit = new Retrofit.Builder()    .client(mOkhttpClient)    .baseUrl("your_serverl_url")    .build();

看,只需在Retrofit中多加一句

.client(mOkhttpClient)

就把已安装了证书的mOkhttpClient作为Retrofit的传输了


更多内容,请关注微信公众号:颜家大少
Https系列之四:https的SSL证书在Android端基于okhttp,Retrofit的使用

原标题:Https系列之四:https的SSL证书在Android端基于okhttp,Retrofit的使用

关键词:Android

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

可能感兴趣文章

我的浏览记录