Android端支持webview。当访问使用ssl加密的url时(即为https协议请求),如果不经过处理,页面显示空白。而使用系统自带的浏览器打开时,会弹出确认证书的对话框。需要的处理是重写WebViewClient类的onReceivedSslError方法,如下:
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
//webview对https协议请求的处理
handler.proceed();
}
Https请求的两种处理方式(1.忽略证书验证 2.https单向证书验证)
一、
/**
* 信任所有主机-对于任何证书都不做检查 (https协议)
*/
private static void trustAllHosts() {
// 创建一个信任管理器不验证SSL证书检查链
TrustManager[] trustAllCerts =
new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
}};
// 设置信任所有主机
try {
SSLContext sc = SSLContext.
getInstance(
"TLS");
sc.init(
null,trustAllCerts ,
null);
HttpsURLConnection.
setDefaultSSLSocketFactory(sc.getSocketFactory());
}
catch (Exception e) {
e.printStackTrace();
}
}
二、
/**
* 设置忽略SSL证书检查
*/
private static final HostnameVerifier
DO_NOT_VERIFY =
new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
三、
/**
* https证书单向认证
*
@param
context
*/
private static void AuthenticationHosts(Context context){
CertificateFactory cf =
null;
try {
//读取证书
cf = CertificateFactory.
getInstance(
"X.509");
InputStream in = context.getAssets().open(
"client.crt");
Certificate ca = cf.generateCertificate(in);
// 初始化keyStore,用来导入证书
KeyStore keystore = KeyStore.
getInstance(KeyStore.
getDefaultType());
//参数null 表示使用系统默认keystore,也可使用其他keystore(需事先将srca.cer 证书导入keystore 里
keystore.load(
null,
null);
// 把client.crt 这个证书导入到KeyStore 里,别名叫做ca
keystore.setCertificateEntry(
"ca", ca);
//通过信任管理器获取一个默认的算法
String tmfAlgorithm = TrustManagerFactory.
getDefaultAlgorithm();
//算法工厂创建
TrustManagerFactory tmf = TrustManagerFactory.
getInstance(tmfAlgorithm);
//用我们设定好的TrustManager 去做ssl 通信协议校验,即证书校验
tmf.init(keystore);
SSLcontext = SSLContext.
getInstance(
"TLS");
SSLcontext.init(
null, tmf.getTrustManagers(),
null);
}
catch (CertificateException e) {
e.printStackTrace();
}
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
catch (KeyStoreException e) {
e.printStackTrace();
}
catch (KeyManagementException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
1.https 请求的忽略证书的方式:
使用方式:
URL url =
new URL(requestUrl);
if (url.getProtocol().toLowerCase().equals(
"https")) {
//信任所有主机(如果需要证书验证请在此处调用AuthenticationHosts()方法,并与下文https.setSSLSocketFactory(SSLcontext.getSocketFactory());联合使用)
trustAllHosts();
//创建https链接
HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
//设置ip授权认证:如果已经安装该证书,可以不设置,否则需要设置
https.setHostnameVerifier(
DO_NOT_VERIFY);
conn = https;
}
else {
conn = (HttpURLConnection) url.openConnection();
}
2.https 请求的单向验证证书的方式:
使用方式:
URL url =
new URL(requestUrl);
if (url.getProtocol().toLowerCase().equals(
"https")) {
//设置SSL证书的相关处理
AuthenticationHosts(context);
//创建https链接
HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
//设置证书认证
https.setSSLSocketFactory(SSLcontext.getSocketFactory());
//设置ip授权认证:如果已经安装该证书,可以不设置,否则需要设置
https.setHostnameVerifier(
DO_NOT_VERIFY);
conn = https;
}
else {
conn = (HttpURLConnection) url.openConnection();
}