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();
}