上文讲述的加载https的时候,不使用证书安全校验。本文讲述-------使用OkHttp请求自签名的https网站
-
1、首先在安卓项目中,引入网站的自签名文件,如下图
- 2、建立HttpsUtils工具类,返还一个有签名校验 的OkHttpClient对象
package com.zdk.mg.mgworkstore.util;
import android.content.Context;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.util.Arrays;
import java.util.Collection;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import okhttp3.OkHttpClient;
/**
* Created by Administrator on 2017/11/17.
*/
public class HttpsUtils {
private static HttpsUtils instance;
private HttpsUtils (){}
public static synchronized HttpsUtils getInstance() {
if (instance == null) {
instance = new HttpsUtils();
}
return instance;
}
public OkHttpClient getUnsafeOkHttpClient(Context context) {
X509TrustManager trustManager;
SSLSocketFactory sslSocketFactory;
final InputStream inputStream;
try {
inputStream = context.getAssets().open("certificate.pem"); // 得到证书的输入流
trustManager = trustManagerForCertificates(inputStream);//以流的方式读入证书
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[]{trustManager}, null);
// Create an ssl socket factory with our all-trusting manager
sslSocketFactory = sslContext
.getSocketFactory();
OkHttpClient okHttpClient = new OkHttpClient()
.newBuilder()
.sslSocketFactory(sslSocketFactory)
.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return hostname.equals(session.getPeerHost());
}
}).build();
return okHttpClient;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 以流的方式添加信任证书
*/
private X509TrustManager trustManagerForCertificates(InputStream in)
throws GeneralSecurityException {
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
Collection certificates = certificateFactory.generateCertificates(in);
if (certificates.isEmpty()) {
throw new IllegalArgumentException("expected non-empty set of trusted certificates");
}
// Put the certificates a key store.
char[] password = "password".toCharArray(); // Any password will work.
KeyStore keyStore = newEmptyKeyStore(password);
int index = 0;
for (Certificate certificate : certificates) {
String certificateAlias = Integer.toString(index++);
keyStore.setCertificateEntry(certificateAlias, certificate);
}
// Use it to build an X509 trust manager.
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, password);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:"
+ Arrays.toString(trustManagers));
}
return (X509TrustManager) trustManagers[0];
}
/**
* 添加password
* @param password
* @return
* @throws GeneralSecurityException
*/
private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException {
try {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); // 这里添加自定义的密码,默认
InputStream in = null; // By convention, 'null' creates an empty key store.
keyStore.load(in, password);
return keyStore;
} catch (IOException e) {
throw new AssertionError(e);
}
}
}
- 3、在初始化Fresco的时候,(或者用OkHttp调用网络接口的时候),使用上边的OkHttpClient对象即可
private void FrescoInit() {
OkHttpClient okHttpClient= HttpsUtils.getInstance().getUnsafeOkHttpClient(this); // build on your own
ImagePipelineConfig config = OkHttpImagePipelineConfigFactory
.newBuilder(this, okHttpClient)
.build();
Fresco.initialize(this, config);
}
欢迎收看我的上篇博文 https跳过证书验证--当Fresco/Picasso遇到https(1)
作者:ZhangYushui
來源:
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。