一:https的简单介绍及SSL证书的生成
二:https的SSL证书在服务器端的部署,基于tomcat,spring boot
三:让服务器同时支持http、https,基于spring boot
四:https的SSL证书在Android端基于okhttp,Retrofit的使用vue
全部文章会优先在:
微信公众号“颜家大少”中发布
转载请标明出处java
前面已分别介绍了https,SSL证书的生成,并完成了服务器端的https的部署
并提到一个重要的用于客户端的证书:公钥证书
在前面文章中,自签名SSL证书对应的公钥证书为:mycer.cer(固然这名字是本身随便定的);在阿里云申请的CA证书中对应的公钥证书为:*.pem
若是有不清楚的,请看我以前介绍过的文章android
还要说明一下,Android系统有自带的安卓承认的证书颁发机构(如:Wosign)颁发的可信任的CA公钥证书,大概有100多个,
可本身查看,各个手机的查看方法可能不同,在个人手机中,能在下面的位置中找到:
“设置”->”更多设置“->”系统安全“->”信任的凭据”
也就是说,若是你服务器的证书是安卓承认的证书颁发机构颁发的,那么你并不须要在Android端额外安装公钥证书,不然,你就须要安装。
注:在不一样版本的Android系统上,可信任的CA证书多是不同的,若是你担忧在别人的Android系统上可能此CA证书不被信任,那你统一都安装也是没问题的
我在阿里云上申请的免费型DV SSL证书,是属于安卓承认的证书颁发机构颁发的,不须要额外安装,固然咱们的自签名证书,是必须要安装的
其实我在测试的过程当中,把自签名证书和阿里云上申请的免费型DV SSL证书都用一样的方法安装了,都是OK的spring
先看看个人okhttp和retrofit的gradle版本tomcat
compile 'com.squareup.okhttp3:okhttp:3.8.1' compile 'com.squareup.retrofit2:retrofit:2.3.0'
统一处理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进去markdown
而后经过app
trustManager =trustManagerForCertificates(getTrustrCertificates());
再
okHttpClient=new OkHttpClient.Builder() .sslSocketFactory(sslSocketFactory, trustManager) .build();
就能生成安装好了可信任证书的okHttpClient
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默认是以OkHttpClient来做为传输的,既然OkHttpClient搞掂了,那Retrofit就简单了
仍是直接贴代码:
Retrofit retrofit = new Retrofit.Builder() .client(mOkhttpClient) .baseUrl("your_serverl_url") .build();
看,只需在Retrofit中多加一句
.client(mOkhttpClient)
就把已安装了证书的mOkhttpClient做为Retrofit的传输了
更多内容,请关注微信公众号:颜家大少