android okhttp3 配置https证书

一、写在前面,客户端的证书,一般是由服务端提供的,我们来认识一下:

ca.crt       :服务端证书

client.crt  :客户端证书

client.key :客户端证书秘钥

ca.crt就是我们客户端单向验证时使用的证书, 那么client.crt和client.key就应该是双向验证用到的bks了,于是重点就是他们间的转换了

准备工作,我们用到两个工具:

openssl:证书格式转换及秘钥获取

            下载地址:https://download.csdn.net/download/hhbbeijing/13454495

keytool:

介绍:OpenSSL整个软件包大概可以分成三个主要的功能部分:SSL协议库、应用程序以及密码算法库。OpenSSL的目录结构自然也是围绕这三个功能部分进行规划的。作为一个基于密码学的安全开发包,OpenSSL提供的功能相当强大和全面,囊括了主要的密码算法、常用的密钥和证书封装管理功能以及SSL协议,并提供了丰富的应用程序供测试或其它目的使用。

 

二、正文

先看一段okhttps创建的代码:

OkHttpClient.Builder builder = new OkHttpClient().newBuilder()
        .connectTimeout(15, TimeUnit.SECONDS)
        .readTimeout(15,TimeUnit.SECONDS)
        .addNetworkInterceptor(logInterceptor)
        .hostnameVerifier(new MYHostnameVerifier(HOSTNAME));
if(trustManager != null){
    //SSLSocketFactory X509TrustManager
    builder.sslSocketFactory(getSSLSocketFactory(trustManager),trustManager);
}
mOkHttpClient = builder.build();

需要两个参数:

SSLSocketFactory:(2):   BKS_PWD  JKSNAME

trustManager:(1)  其中CERTNAME是信任的服务端证书,但格式为cer,由ca.crt格式转换而来。(可以直接修改后缀)

 

(1):

private X509TrustManager getTrustManager(){
    InputStream certificate = null;
    X509TrustManager trustManager = null;
    try {
        certificate = mContext.getAssets().open(CERTNAME);
        trustManager = trustManagerForCertificates(certificate);
    } catch (Exception e) {
        //e.printStackTrace();
    }
    return trustManager;
}

(2):

private SSLSocketFactory getSSLSocketFactory(X509TrustManager trustManager) throws NoSuchAlgorithmException, KeyManagementException {
    SSLContext context = SSLContext.getInstance("TLS");
    TrustManager[] trustManagers = {trustManager};
    KeyManager[] keyManagers = getKeyManager();
    context.init(keyManagers, trustManagers, new SecureRandom());
    return context.getSocketFactory();
}

private KeyManager[] getKeyManager() {
    try {
        String pwd = BKS_PWD;
        InputStream bks = mContext.getAssets().open(JKSNAME);
        KeyStore clientKeyStore = KeyStore.getInstance("BKS");
        clientKeyStore.load(bks, pwd.toCharArray());
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(clientKeyStore, pwd.toCharArray());
        return keyManagerFactory.getKeyManagers();
    } catch (Exception e) {
        //e.printStackTrace();
    }
    return null;
}

重点来了,如何

1、android平台能识别的客户端证书 为:.bks格式的,需要格式转换,分两步:

    第一步,将 client.crt 和 client.key转换成 client.p12

   openssl pkcs12 -export -in client.crt -inkey client.key -out client.p12 -name tomcat -CAfile ca.crt -caname root -chain

  第二步,把.p12格式转换成.bks

  使用 【portecle】工具转换为 .bks (JKSNAME),记住输入的密码 (BKS_PWD)。

2、由ca.crt格式转换而来。(可以直接修改后缀)或者  openssl x509 -in ca.crt -out server.cer -outform der

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

至此全部完成。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

参考文献:

https://blog.csdn.net/liudehuaii18/article/details/50373652

 

上一篇:Android ROM开发(二)——ROM架构以及Updater-Script脚本分析,常见的Status错误解决办法


下一篇:兼容安卓和ios实现一键复制内容到剪切板