[置顶] NoHttp详解之Android使用Https

NoHttp如何使用Https

QQ技术交流1群:46523908
QQ技术交流2群:46505645
NoHttp 源码及Demo: https://github.com/Y0LANDA/NoHttp

NoHttp是专门做Android网络请求与下载的框架。

分析

  • Android发起Https请求时分为两种情况,分为需要安全证书和不需要安全证书两种情况。
  • NoHttp对于Https也很好的支持了,只需要为每一个请求设置SSLSocketFactory即可。

1. 需要证书的情况

首先需要一个SSLSocketFactory,下面是加载证书的代码,是Java和Android通用的,我们只需要SSLContext:

/** * 拿到https证书SSLContext (NoHttp已经修补了系统的SecureRandom的bug) */
@SuppressLint("TrulyRandom")
public static SSLContext getSSLContext() {
    SSLContext sslContext = null;
    try {
        sslContext = SSLContext.getInstance("TLS");
        // 加载证书流, 这里证书需要放在assets下
        InputStream inputStream = Application.getInstance().getAssets().open("srca.cer");

        // 生成证书
        CertificateFactory cerFactory = CertificateFactory.getInstance("X.509");
        Certificate cer = cerFactory.generateCertificate(inputStream);

        // 加载证书到KeyStore
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        keyStore.load(null, null);
        keyStore.setCertificateEntry("trust", cer);

        // 把KeyStore放入keyManagerFactory
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(keyStore, null);

        // KeyStore加入TrustManagerFactory
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(keyStore);

        // 初始化SSLContext
        sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
    } catch (Exception e) {
        e.printStackTrace();
    }

    return sslContext;
}

2. 不需要证书情况

/** * 如果不需要https证书.(NoHttp已经修补了系统的SecureRandom的bug) */
public static SSLContext getDefaultSLLContext() {
    SSLContext sslContext = null;
    try {
        sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, new TrustManager[]{trustManagers}, new SecureRandom());
    } catch (Exception e) {
        e.printStackTrace();
    }
    return sslContext;
}

/** * 信任管理器 */
private static TrustManager trustManagers = new X509TrustManager() {
    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }

    @Override
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[0];
    }
};

/** * 域名验证 */
public static final HostnameVerifier HOSTNAME_VERIFIER = new HostnameVerifier() {
    public boolean verify(String hostname, SSLSession session) {
        return true;
    }
};

为Request对象设置SSLSocketFactory

需要证书

RequestQueue queue = NoHttp.newRequestQueue();
...

Request<String> httpsRequest = NoHttp.createStringRequest(httpsUrl, RequestMethod);
SSLContext sslContext = getSSLContext();
if (sslContext != null) {
    SSLSocketFactory socketFactory = sslContext.getSocketFactory();
    httpsRequest.setSSLSocketFactory(socketFactory);
}
queue.add(0, httpsRequest, OnResponseListener);

不需要证书

RequestQueue queue = NoHttp.newRequestQueue();
...

Request<String> httpsRequest = NoHttp.createStringRequest(httpsUrl, RequestMethod);
SSLContext sslContext = getDefaultSLLContext();// 方法见上文
if (sslContext != null) {
    SSLSocketFactory socketFactory = sslContext.getSocketFactory();
    httpsRequest.setSSLSocketFactory(socketFactory);
}
httpsRequest.setHostnameVerifier(HOSTNAME_VERIFIER);// 见上文
queue.add(0, httpsRequest, OnResponseListener);

好了, 收工, 我去赶最后一趟回家的车了

NoHttp 源码及Demo https://github.com/Y0LANDA/NoHttp

你可能感兴趣的:(android,https,https证书,okhttp,NoHttp)