一、写在前面,客户端的证书,一般是由服务端提供的,我们来认识一下:
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