Retrofit支持https

来源:互联网 发布:2018人工智能大会 编辑:程序博客网 时间:2024/06/05 22:46

1信任所有https请求

okHttpClient设置sslSocketFactory,hostnameVerifier

OkHttpClient okHttpClient = new OkHttpClient.Builder()                .connectTimeout(5, TimeUnit.SECONDS)                .readTimeout(10, TimeUnit.SECONDS)                .sslSocketFactory(getSSLSocketFactory(),new TrustAllCerts())                .hostnameVerifier(getHostnameVerifier())                .build();Retrofit retrofit = new Retrofit.Builder().baseUrl(url)                .client(okHttpClient)                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())                .addConverterFactory(GsonConverterFactory.create())                .build();

getSSLSocketFactory()方法如下:

public static SSLSocketFactory getSSLSocketFactory() {        SSLSocketFactory ssfFactory = null;        try {            SSLContext sc = SSLContext.getInstance("TLS");            sc.init(null, new TrustManager[]{new CustomTrustManager()}, new SecureRandom());            ssfFactory = sc.getSocketFactory();        } catch (Exception e) {        }        return ssfFactory;    }

其中CustomTrustManager类很简单只需实现X509TrustManager

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

getHostnameVerifier()如下,return true就可以

public static HostnameVerifier getHostnameVerifier() {  HostnameVerifier   hostnameVerifier= new HostnameVerifier() {  public boolean verify(String hostname, SSLSession session) {                 return true;            }        };        return hostnameVerifier;    }

2信任证书和指定的url地址

改动上面getSSLSocketFactory(),getHostnameVerifier()方法即可,代码如下:

public static int[] certificates = {R.raw.mycer};    protected static SSLSocketFactory getSSLSocketFactory(Context context, int[] certificates) {        if (context == null) {            throw new NullPointerException("context == null");        }        CertificateFactory certificateFactory;        SSLContext sslContext=null;        try {            certificateFactory = CertificateFactory.getInstance("X.509");            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());            keyStore.load(null, null);            for (int i = 0; i < certificates.length; i++) {                InputStream certificate = context.getResources().openRawResource(certificates[i]);                keyStore.setCertificateEntry(String.valueOf(i), certificateFactory.generateCertificate(certificate));                if (certificate != null) {                    certificate.close();                }            }            sslContext = SSLContext.getInstance("TLS");            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());            trustManagerFactory.init(keyStore);            sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());        }catch (Exception e){            e.printStackTrace();        }        return sslContext.getSocketFactory();    }

R.raw.mycer是自行导入在res/raw/Mycer.cer证书,如图

Jietu20171122-112229@2x.png

getHostnameVerifier()代码如下

 public  static String urls[] = {"url1","url2"};    public static HostnameVerifier getHostnameVerifier() {        HostnameVerifier hostnameVerifier = new HostnameVerifier() {            public boolean verify(String hostname, SSLSession session) {                boolean verifier = false;                for (String host : urls) {                    if (host.equalsIgnoreCase(hostname)) {                        verifier = true;                    }                }                return verifier;            }        };        return hostnameVerifier;    }

上面public static String urls[] = {“url1”,”url2”},url1,url2是你需要信任的服务器地址,例如上方new Retrofit.Builder().baseUrl(url)中url=”https://test2-mytest.com:8888/mytest/”,url1相对应就是test2-mytest.com,验证时会自动去掉https。

上述四个方法可任意组合,信任指定路径,或者所有路径,带证书或者不带证书。

原创粉丝点击