客户端与服务端忽略证书校验即是在客户端的网络请求和webview中设置信任所有证书,然后在与服务端进行Https网络通信的时候,客户端不必进行证书校验也能进行网络通信,否则就会报证书不受信异常。
缺陷:容易受到中间人攻击。
X509TrustManager
和HostnameVerifier
X509TrustManager用于实现SSL证书
的安全校验,若使用不当,将导致APP对SSL证书不作校验,从而 黑客有了中间人攻击的可乘之机。开发者常见错误:
HostnameVerifier用于实现HTTPS通信中的域名
安全校验,即验证当前连接的HTTPS站点的SSL证书中的域名是否等于站点本身的域名。开发者常见错误:
org.apache.http.conn.ssl.AllowAllHostnameVerifier
org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
工具类下载地址:https://download.csdn.net/download/u010982507/10880268
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
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 null; 或者
return new X509Certificate[]{}; // 空实现
}
}
};
return trustAllCerts;
}
//获取HostnameVerifier
public static HostnameVerifier getHostnameVerifier() {
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
// true表示信任所有域名
return true;
}
};
return hostnameVerifier;
}
}
使用Android系统中自带的不安全的HostnameVerifie
URL url = new URL("https url");
HttpsURLConnection conn= (HttpsURLConnection) url.openConnection();
conn.setHostnameVerifier(org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpURLConnection
信任所有证书URL url = new URL(fileUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod(requestType);
conn.setConnectTimeout(timeOut * 1000);
// 配置https的证书
if ("https".equalsIgnoreCase(url.getProtocol())){
((HttpsURLConnection) conn).setSSLSocketFactory(SSLSocketClient.getSSLSocketFactory());
((HttpsURLConnection) conn).setHostnameVerifier(SSLSocketClient.getHostnameVerifier());
}
OkHttp
信任所有证书OkHttpClient okHttpClient = new OkHttpClient.Builder()
.sslSocketFactory(SSLSocketClient.getSSLSocketFactory())
.hostnameVerifier(SSLSocketClient.getHostnameVerifier())
.build();
webview
信任所有证书Android系统内置了一些可信机构办法的证书,可用于作HTTPS证书校验。实际上,使用Webview组件进HTTPS通信,其证书验证环节也是系统默认会去做的。若发现证书不合法,Webview将显示一个空白页面,其错误在onReceivedSslError()这个方法里进行处理。
在WebViewClient源码中可以看到系统默认处理,是拒绝连接带有可信机构颁发证书的HTTPS站点的,如下所示:
/**
* Notify the host application that an SSL error occurred while loading a
* resource. The host application must call either handler.cancel() or
* handler.proceed(). Note that the decision may be retained for use in
* response to future SSL errors. The default behavior is to cancel the
* load.
*
* @param view The WebView that is initiating the callback.
* @param handler An SslErrorHandler object that will handle the user's
* response.
* @param error The SSL error object.
*/
public void onReceivedSslError(WebView view, SslErrorHandler handler,
SslError error) {
// 拒绝连接
handler.cancel();
}
而我们重写此方法的时候可以设置成接受所有连接,如下所示:
public void onReceivedSslError(WebView view, SslErrorHandler handler,
SslError error) {
// 接受所有连接
handler.proceed();
}
参考:
https://blog.csdn.net/jogger_ling/article/details/60576625
https://blog.csdn.net/u012852986/article/details/78873387
https://blog.csdn.net/Hubert_bing/article/details/55258280