一、https證書
對於https和證書的概念,大家可以自行搜索百度。
證書分兩種:
1、花錢向認證機構購買的證書,(我們公司買的證書一個就需要4000元,TMD,還不如多租一台服務器)。服務器如果使用了此類證書的話,那對於移動端來說,直接可以忽略此證書,直接用https訪問。與之不同的是ios內置了很多信任的證書,所以他們不需要做任何操作
2、另一種是自己制作的證書,使用此類證書的話是不受信任的,也不需要花錢,所以需要我們在代碼中將此類證書設置為信任證書
二、如何忽略證書
1、服務器的哥們如果加上了證書的話,那么你們的網絡請求的url將從http:xx改成https:xx,如果你直接也將http改成https的話而什么也不做的話,客戶端將直接報錯,如圖:
意思就是沒有找到本地證書,那就開始構建一個SSL來信任所有的證書,忽略證書其實就是如此。
2、新建一個類
public class SSLSocketClient {
//獲取這個SSLSocketFactory
public static SSLSocketFactory getSSLSocketFactory() {
try {
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, getTrustManager(), new SecureRandom());
return sslContext.getSocketFactory();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//獲取TrustManager
private static TrustManager[] getTrustManager() {
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[]{};
}
}
};
return trustAllCerts;
}
}
通過這個類我們可以獲得SSLSocketFactory,這個東西就是用來管理證書和信任證書的
但是有一點需要注意:
然后我們在okhttp中設置SSLSocketFactory,如圖:
運行之后,發現還是會報錯,如圖:
意思是我們的請求證書和服務器的證書不一致,這是因為我們還需要配置一個HostnameVerifier來忽略host驗證
三、在SSLSocketClient的類中再加入一個方法:
//獲取HostnameVerifier
public static HostnameVerifier getHostnameVerifier() {
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
};
return hostnameVerifier;
}
然后再okhttp中配置一下HostnameVerifier:
在運行,可以正常訪問了
四、整體配置
copy整個工具類到你的項目中:
/**
* Created by Anonymous on 2017/6/13.
*/
public class SSLSocketClient {
//獲取這個SSLSocketFactory
public static SSLSocketFactory getSSLSocketFactory() {
try {
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, getTrustManager(), new SecureRandom());
return sslContext.getSocketFactory();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//獲取TrustManager
private static TrustManager[] getTrustManager() {
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[]{};
}
}
};
return trustAllCerts;
}
//獲取HostnameVerifier
public static HostnameVerifier getHostnameVerifier() {
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
};
return hostnameVerifier;
}
}
然后再okhttp中配置
mHttpClient = new OkHttpClient().newBuilder()
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.addInterceptor(new LogInterceptor())
.addInterceptor(new TokenInterceptor())
.sslSocketFactory(SSLSocketClient.getSSLSocketFactory())//配置
.hostnameVerifier(SSLSocketClient.getHostnameVerifier())//配置
.build();
如果你用的是retrofit,在retrofit中配置一下okhttp即可
retrofitAPI = new Retrofit.Builder()
.baseUrl(AppConfig.baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(mHttpClient)//配置okhttp
.build()
.create(RetrofitAPI.class);