工作需要使用到 Android  加密传输(SSL),双向认证 ,因为未使用过,所以搜索了总结了一下相关知识,并整理作为笔记

参考博客 :Retrofit 2.0 详解(二)加载https请求(转)

                   Android实现ssl双向验证

搜索的时候关于SSL+http 的解释有很多,不做细说,本文只记录如何实现,包括证书制作、myeclipse服务部署以及Android端代码。

证书制作

打开cmd命令窗口

1、生成客户端keystore

keytool -genkeypair -alias E:\sslhttpTest\keystool\client -keyalg RSA -validity 3650 -keypass 123456 -storepass 123456 -keystore E:\sslhttpTest\keystool\client.jks

Android 加密传输(SSL),双向认证 笔记_第1张图片

注:此处 E:\sslhttpTest\keystool\client  是本人手误 只需输入 client 即可,alias 无需路径

2、生成服务端keystore

keytool -genkeypair -alias server -keyalg RSA -validity 3650 -keypass 123456 -storepass 123456 -keystore E:\sslhttpTest\keystool\server.keystore

Android 加密传输(SSL),双向认证 笔记_第2张图片

3、导出客户端证书

keytool -export -alias E:\sslhttpTest\keystool\client -file E:\sslhttpTest\keystool\client.cer -keystore E:\sslhttpTest\keystool\client.jks -storepass 123456

4、导出服务端证书

keytool -export -alias server -file E:\sslhttpTest\keystool\server.cer -keystore E:\sslhttpTest\keystool\server.keystore -storepass 123456

5、重点:证书交换

将客户端证书导入服务端keystore中,再将服务端证书导入客户端keystore中, 一个keystore可以导入多个证书,生成证书列表。

生成客户端信任证书库(由服务端证书生成的证书库):

keytool -import -v -alias server -file E:\sslhttpTest\keystool\server.cer -keystore E:\sslhttpTest\keystool\truststore_s_for_c.jks -storepass 123456

Android 加密传输(SSL),双向认证 笔记_第3张图片

将客户端证书导入到服务器证书库(使得服务器信任客户端证书):

keytool -import -v -alias E:\sslhttpTest\keystool\client -file E:\sslhttpTest\keystool\client.cer -keystore E:\sslhttpTest\keystool\client_for_server.keystore -storepass 123456

Android 加密传输(SSL),双向认证 笔记_第4张图片

6、生成Android识别的BKS库文件

下载地址: protecle.jar 百度网盘下载地址

运行protecle.jar将client.jkstruststore_s_for_c.jks分别转换成client.bkstruststore_s_for_c.bks ,然后放到android客户端的assert目录下

File -> open Keystore File -> 选择证书库文件 -> 输入密码 -> Tools -> change keystore type -> BKS -> save keystore as -> 保存即可

7、配置Tomcat服务器(可选)

找到Tomcat安装目录 conf\server.xml文件,配置8443端口

注:

可以不配置tomcat ,只需配置 eclipse 的工程目录中的对应的server.xml文件 E:\eclipsework\.metadata\.me_tcat7\conf\server.xml(我的工程目录在E:\eclipsework 根据实际情况找路径) 。如果 eclipsework\.metadata\.me_tcat7 的目录下没有 conf 目录,需要新建conf文件夹然后将 tomcat 安装目录 conf\server.xml文件复制过来,然后启动myeclipse的服务,会报错 根据报错删除

即可,配置 server.xml 的端口

Android 端配置

        SSLHelper

import android.content.Context;import java.io.IOException;import java.io.InputStream;import java.security.KeyManagementException;import java.security.KeyStore;import java.security.KeyStoreException;import java.security.NoSuchAlgorithmException;import java.security.UnrecoverableKeyException;import java.security.cert.CertificateException;import javax.net.ssl.KeyManagerFactory;import javax.net.ssl.SSLContext;import javax.net.ssl.SSLSocketFactory;import javax.net.ssl.TrustManagerFactory;public class SSLHelper {    private static final String TAG = "SSLHelper";    private final static String CLIENT_PRI_KEY = "client";    private final static String TRUSTSTORE_PUB_KEY = "truststore_s_for_c";    private final static String CLIENT_BKS_PASSWORD = "123456";    private final static String TRUSTSTORE_BKS_PASSWORD = "123456";    private final static String KEYSTORE_TYPE = "BKS";    private final static String PROTOCOL_TYPE = "TLS";    private final static String CERTIFICATE_FORMAT = "X509";    public static SSLSocketFactory getSSLCertifcation(Context context) {        SSLSocketFactory sslSocketFactory = null;        try { // 服务器端需要验证的客户端证书,其实就是客户端的keystore            KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE);// 客户端信任的服务器端证书            KeyStore trustStore = KeyStore.getInstance(KEYSTORE_TYPE);//读取证书            InputStream ksIn = context.getAssets().open(CLIENT_PRI_KEY);            InputStream tsIn = context.getAssets().open(TRUSTSTORE_PUB_KEY);//加载证书            keyStore.load(ksIn, CLIENT_BKS_PASSWORD.toCharArray());            trustStore.load(tsIn, TRUSTSTORE_BKS_PASSWORD.toCharArray());            ksIn.close();            tsIn.close(); //初始化            SSLContext sslContext = SSLContext.getInstance(PROTOCOL_TYPE);            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(CERTIFICATE_FORMAT);            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(CERTIFICATE_FORMAT);            trustManagerFactory.init(trustStore);            keyManagerFactory.init(keyStore, CLIENT_BKS_PASSWORD.toCharArray());            sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);            sslSocketFactory = sslContext.getSocketFactory();        } catch (KeyStoreException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        } catch (CertificateException e) {            e.printStackTrace();        } catch (NoSuchAlgorithmException e) {            e.printStackTrace();        } catch (UnrecoverableKeyException e) {            e.printStackTrace();        } catch (KeyManagementException e) {            e.printStackTrace();        }        return sslSocketFactory;    }}
UnSafeTrustManager
public class UnSafeTrustManager implements 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[]{};        }    }
Retrofit 初始化
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);        //创建okhttp        OkHttpClient httpClient = new OkHttpClient().newBuilder()                .addInterceptor(interceptor)                .retryOnConnectionFailure(true)                .connectTimeout(30, TimeUnit.SECONDS)                .sslSocketFactory(SSLHelper.getSSLCertifcation(context), new UnSafeTrustManager())                .hostnameVerifier(new HttpsUtil.UnSafeHostnameVerifier())//由于还没有域名,此处设置忽略掉域名校验                .build();        retrofit=new Retrofit.Builder()                .baseUrl(url)                .client(httpClient)                .addConverterFactory(GsonConverterFactory.create())                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())                .build();

 

所有代码可以在百度网盘下载

百度网盘链接:测试程序下载

密码:on6o

目录说明:keystool.zip 测试证书压缩包

                  LoginSSL.zip 测试后台压缩包

                  SSLTest.zip 测试Android 压缩包 ,使用时请替换 MainActivity中的 url 地址的 ip 修改为测试的IP地址

 

 

 

 

 

 

 

 

 

 

 

 

 

 

更多相关文章

  1. Android上传文件,客户端+服务器源码
  2. Android 的网络编程(15)-Http JSon服务器端和客户端通信
  3. Android 博客园客户端 (一) 基本界面
  4. android微博客户端源代码
  5. Android客户端与J2EE服务器的互联
  6. 让Android Studio支持系统签名(证书)
  7. Android keytool 生成证书MD5指纹
  8. 调用android手机微博客户端发送微博

随机推荐

  1. 30个Linux Shell脚本经典案例(下)
  2. 10 个Linux Awk文本处理经典案例
  3. Python 发送邮件各种姿势
  4. Kubernetes Dashboard v2.0.0 尝鲜
  5. Kubeadm 部署高可用 K8S 集群
  6. 解决docker服务默认网卡和宿主机网卡内网
  7. 一个简单的Java计时器项目,附源码
  8. RSA加密的填充方式
  9. 什么是技术分析(Technical Analysis)指标库
  10. PHP语言之华为应用内支付IAP验签