webView证书校验:
通过chrome浏览器拿到证书cer文件
获取证书公钥
public void readX509CerFile() {
try {
InputStream inStream = getAssets().open("ccc.cer");
// 创建X509工厂类
CertificateFactory cf = CertificateFactory.getInstance("X.509");
// 创建证书对象
X509Certificate oCert = (X509Certificate) cf
.generateCertificate(inStream);
inStream.close();
String info = null;
// 获得证书版本
Log.d(TAG, "publicKey: " + oCert.getPublicKey());
} catch (Exception e) {
e.printStackTrace();
}
}
证书公钥类
public class SslCert {
public static final String[] keys = new String[]{
"30820122300d06092a864886f70d01010105000382010f003082010a0282010100证书公钥0203010001"
};
}
判断证书接口类
public class SslInterfance {
public interface SslInterfase {
void signSslResult(boolean result);
}
private static SslInterfase mSslInterfase;
public static void setSslInterfase(SslInterfase sslInterfase) {
mSslInterfase = sslInterfase;
}
public static void getUnsafeFromService(String url) {
String[] publicKeys = SslCert.keys;
try {
X509TrustManager[] trustManagers = new X509TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
if (x509Certificates == null) {
throw new IllegalArgumentException("check Service x509Certificates is null");
}
boolean expected = false;
for (X509Certificate certificate : x509Certificates) {
RSAPublicKey pubkey = (RSAPublicKey) certificate.getPublicKey();
String server = new BigInteger(1 /* positive */, pubkey.getEncoded()).toString(16);
for (String item : publicKeys) {//循环比对公钥,如果在信任列表里就验证成功
if (item.equalsIgnoreCase(server)) {
expected = true;
break;
}
}
}
Log.d("AAAAAAAAAQ", "expected: " + expected);
mSslInterfase.signSslResult(expected);
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
};
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagers, null);
final HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
HostnameVerifier hostnameVerifier1 = HttpsURLConnection.getDefaultHostnameVerifier();
boolean result = hostnameVerifier1.verify("*", session);
return result;
}
};
OkHttpClient okHttpClient = new OkHttpClient.Builder().hostnameVerifier(hostnameVerifier).sslSocketFactory(sslContext.getSocketFactory(), trustManagers[0]).build();
// String url = "https://www.baidu.com";
Request request = new Request.Builder().url(url).build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// Log.d("AAAAAAAAAQ", "onFailure: " + e.getMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String res = response.body().string();
// Log.d("AAAAAAAAAQ", "onResponse: " + res);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
加载webView界面
SslInterfance.setSslInterfase(this);
SslInterfance.getUnsafeFromService(url);
回调方法
@Override
public void signSslResult(boolean result) {
Log.d("AAAAAAAS", "signSslResult: " + result);
if (result) {
loadUrl(url);
} else {
loadUrl("file:///android_asset/Demo/blank.html");
new Thread() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MAMCordovaActivity.this, "当前界面证书验证失败!", Toast.LENGTH_SHORT).show();
}
});
}
}.start();
}
}
接口证书校验:
判断证书公钥方法
class PubKeyManager implements X509TrustManager {
String[] publicKeys = SslCert.keys;
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
//锁定证书公钥在apk中
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
if (chain == null) {
throw new IllegalArgumentException(
"checkServerTrusted: X509Certificate array is null");
}
if (!(chain.length > 0)) {
throw new IllegalArgumentException(
"checkServerTrusted: X509Certificate is empty");
}
if (!((null != authType)
&& (authType.equalsIgnoreCase("RSA"))
|| authType.equalsIgnoreCase("ECDHE_RSA"))) {
throw new CertificateException(
"checkServerTrusted: AuthType is not RSA");
}
// Perform customary SSL/TLS checks
try {
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init((KeyStore) null);
for (TrustManager trustManager : tmf.getTrustManagers()) {
((X509TrustManager) trustManager).checkServerTrusted(chain,
authType);
}
} catch (Exception e) {
throw new CertificateException(e);
}
// Hack ahead: BigInteger and toString(). We know a DER encoded Public Key begins
// with 0?30 (ASN.1 SEQUENCE and CONSTRUCTED), so there is no leading 0?00 to drop.
RSAPublicKey pubkey = (RSAPublicKey) chain[0].getPublicKey();
String server = new BigInteger(1 /* positive */, pubkey.getEncoded()).toString(16);
// Pin it!
boolean expected = false;
for (String item : publicKeys) {//循环比对公钥,如果在信任列表里就验证成功
if (item.equalsIgnoreCase(server)) {
expected = true;
break;
}
}
if (!expected) {
throw new CertificateException(
"checkServerTrusted: Expected public key: " + server +
"not in trust");
}
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
创建OkHttpClient
private OkHttpClient okHttpClient = null;
OkHttpClient.Builder b = new OkHttpClient.Builder();
b.cookieJar(new CookieJar() {
private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
cookieStore.put(url.host(), cookies);
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
List<Cookie> cookies = cookieStore.get(url.host());
return cookies != null ? cookies : new ArrayList<Cookie>();
}
}).connectTimeout(connectTimeout, TimeUnit.SECONDS)
.writeTimeout(writeTimeout, TimeUnit.SECONDS)
.readTimeout(readTimeout, TimeUnit.SECONDS);
以上代码通过this.okHttpClient = b.build();可以直接拿到okHttpClient。需要验证https证书需要对OkHttpClient.Builder继续进行操作
OkHttpClient.Builder b = new OkHttpClient.Builder();
b.cookieJar(new CookieJar() {
private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
cookieStore.put(url.host(), cookies);
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
List<Cookie> cookies = cookieStore.get(url.host());
return cookies != null ? cookies : new ArrayList<Cookie>();
}
}).connectTimeout(connectTimeout, TimeUnit.SECONDS)
.writeTimeout(writeTimeout, TimeUnit.SECONDS)
.readTimeout(readTimeout, TimeUnit.SECONDS);
this.okHttpClientForUpdate = b.build();
if (&& URL.startsWith("https")//https
&& (URL.contains(".baidu.com") || URL.contains(".aaaa.com"))//此处可以增加开关人为控制或根据域名控制
) {//cdn
try {
X509TrustManager trustManager;
trustManager = new PubKeyManager();
SSLSocketFactory sslSocketFactory = null;
SSLContext sslContext = null;
sslContext = SSLContext.getInstance("TLS");
//使用构建出的trustManger初始化SSLContext对象
sslContext.init(null, new TrustManager[]{trustManager}, null);
//获得sslSocketFactory对象
sslSocketFactory = sslContext.getSocketFactory();
b.sslSocketFactory(sslSocketFactory, trustManager);
} catch (Exception ex) {
ex.printStackTrace();
}
b.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
boolean verify = HttpsURLConnection.getDefaultHostnameVerifier().verify("*.baidu.com", session)
|| HttpsURLConnection.getDefaultHostnameVerifier().verify("*.baiducdn.com", session);
return verify;
}
});
}
this.okHttpClient = b.build();