基于java的https双向认证,android上亦可用
From: http://my.oschina.net/jjface/blog/339144
概述:
客户端,浏览器或者使用http协议和服务器通信的程序。
如:
客户端通过浏览器访问某一网站时,如果该网站为HTTPS网站,浏览器会自动检测系统中是否存在该网站的信任证书,
如果没有信任证书,浏览器一般会拒绝访问,IE会有一个继续访问的链接,但地址栏是红色,给予用户警示作用,
即客户端验证服务端并不是强制性的,可以没有服务端的信任证书,当然是否继续访问完全取决于用户自己。
如果要去除地址栏的红色警告,需要导入服务端提供的证书到浏览器中。
服务器端,使用http协议提供服务的程序。
服务端需要获取到客户端通过浏览器发送过来的认证证书,
如:
该证书在服务端的证书库中已存在,仅仅是个匹配过程,匹配成功即通过认证,可继续访问网站资源,反之则无法显示网页。
基本逻辑:
1、生成服务端密钥库并导出证书.
2、生成客户端密钥库并导出证书.
3、根据服务端密钥库生成客户端信任的证书.
4、将客户端证书导入服务端密钥库.
5、将服务端证书导入浏览器.
源码下载地址:http://pan.baidu.com/s/1eQ5r9OA
生成密钥库和证书:
因使用java环境,下面使用jdk下面的keytool工具来生成相应的密钥库和证书
下面的命令是在windows 7 下面测试通过的,可以直接复制使用
1、创建目录,如d:/sslDemo
2、使用资源管理进入d:/sslDemo,按住shift+右键,弹出菜单,选择"在此处打开命令行".
3、服务器端相关操作
3.1、生成服务器证书库
keytool -validity 36500 -genkey -v -alias server -keyalg RSA -keystore server.keystore -dname "CN=www.itjoyee.com,OU=itjoyee.com,O=itjoyee.com,L=Wuhan,ST=HuBei,c=cn" -storepass 123456 -keypass 123456
注: 服务器证书库参数“CN”必须与服务端的IP地址相同,否则会报错,客户端的任意。
3.2、从服务器证书库中导出服务器证书
keytool -export -v -alias server -keystore server.keystore -storepass 123456 -rfc -file server.cer
3.3、生成客户端信任证书库(由服务端证书生成的证书库,客户端使用此证书验证服务端来源可靠)
keytool -import -v -alias server -file server.cer -keystore client.truststore -storepass 123456 -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider
注:-storetype BKS 是生成Android上面可以识别的格式,如果不指定jdk默认生成的格式是JKS.
-provider org.bouncycastle.jce.provider.BouncyCastleProvider,需要下载jar包bcprov-jdk16-1.46.jar放到jdk1.7.0_65\jre\lib\ext\目录下.
注意需要jdk16,其他的版本android下面有版本不匹配的问题.
4、客户端相关操作
4.1、生成客户端证书库
keytool -validity 36500 -genkeypair -v -alias client -keyalg RSA -storetype PKCS12 -keystore client.p12 -dname "CN=clients.itjoyee.com,OU=jiajianfa,O=jiajianfa,L=Wuhan,ST=HuBei,c=cn" -storepass 123456 -keypass 123456
4.2、从客户端证书库中导出客户端证书
keytool -export -v -alias client -keystore client.p12 -storetype PKCS12 -storepass 123456 -rfc -file client.cer
注:客户端证书可以产生多个.
4.3、将客户端证书导入到服务器证书库(使得服务器信任客户端证书,服务器端用此验证客户端的合法性)
keytool -import -v -alias client -file client.cer -keystore server.keystore -storepass 123456
4.4、查看服务端证书中信任的客户端证书
keytool -list -keystore server.keystore -storepass 123456
5、服务器端配置
由于使用tomcat,下面使用tomcat做为实例配置.
5.1、在tomcat安装目录下新建key目录,将上面生成的server.keystore复制过去.
5.2、编辑tomcat安装目录下的conf目录下的server.xml,如:d:\sslDemo\apache-tomcat-7.0.55\conf\server.xml
找到Connector,修改如下:
| 
1 
2 
3 
4 
5 
6 
7 | <Connectorport="8444"protocol="org.apache.coyote.http11.Http11NioProtocol"           maxThreads="150"           SSLEnabled="true"scheme="https"secure="true"           keystoreFile="${catalina.base}/key/server.keystore"keystorePass="123456"                      clientAuth="true"sslProtocol="TLS"           truststoreFile="${catalina.base}/key/server.keystore"truststorePass="123456"/> | 
注:           
port配置https访问的端口
SSLEnabled="true" 开启https服务
scheme="https"
secure="true"    开启服务端安全通信,客户端获取服务器端证书
keystoreFile="${catalina.base}/key/server.keystore" keystorePass="123456" 服务器证书库
clientAuth="true" 开启验证客户端
sslProtocol="TLS" 使用的协议
truststoreFile="${catalina.base}/key/server.keystore" truststorePass="123456" 服务器证书库(已导入客户端证书)
6、测试
由于生成证书CN配置的是www.itjoyee.com,故需要修改C:\Windows\System32\drivers\etc\hosts
添加
192.168.0.50    www.itjoyee.com
注:
192.168.0.50 为服务器的ip
启动tomcat
打开浏览器
地址栏输入 http://www.itjoyee.com:8080/
可以访问
地址栏输入https://www.itjoyee.com:8444/
访问结果,为无法显示,因为,没有使服务器端生成的信任的客户端证书
双击client.p12,输入密码,在此访问https://www.itjoyee.com:8444/
此时会有证书相关的提示,点击"确认",接着会提示网站安全证书有问题,点击继续访问,即可进入正常访问页面
7、tomcat下的服务强制使用ssl配置
已ROOT服务为例,修改D:\sslDemo\apache-tomcat-7.0.55\webapps\ROOT\WEB-INF\web.xml
添加
| 
1 
2 
3 
4 
5 
6 
7 
8 
9 | <security-constraint>           <web-resource-collection>        <web-resource-name>SSL</web-resource-name>          <url-pattern>/*</url-pattern>    </web-resource-collection>    <user-data-constraint>        <transport-guarantee>CONFIDENTIAL</transport-guarantee>      </user-data-constraint></security-constraint> | 
打开浏览器
地址栏输入 http://www.itjoyee.com:8080/会有证书相关提示
为了方便测试android下双向认证可以用,生成证书的时候把域名换成服务器的ip地址,验证才可以通过
1、android app 代码实现
| 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 
82 
83 
84 
85 
86 
87 
88 
89 | AsyncTask testTask = newAsyncTask() {            @Override            protectedObject doInBackground(Object... params) {                try{                    HttpClient httpsClient = AppSslApplication.getHttpsClient(MainActivity.this.getBaseContext());                    HttpGet httpget = newHttpGet(HTTPS_URL);                    HttpResponse response = httpsClient.execute(httpget);                    HttpEntity entity = response.getEntity();                    Log.e("Response status", response.getStatusLine().toString());                    if(entity != null) {                        Log.e("Response", "Response content length: "+ entity.getContentLength());                        BufferedReader bufferedReader = newBufferedReader(newInputStreamReader(entity.getContent()));                        String text;                        while((text = bufferedReader.readLine()) != null) {                            Log.e("Response status", text);                        }                        bufferedReader.close();                    }                    httpsClient.getConnectionManager().shutdown();                } catch(ClientProtocolException e) {                    e.printStackTrace();                } catch(IllegalStateException e) {                    e.printStackTrace();                } catch(IOException e) {                    e.printStackTrace();                }                returnnull;            }        };        testTask.execute();publicclassHttpClientSslHelper {    privatestaticfinalString KEY_STORE_TYPE_BKS = "bks";    privatestaticfinalString KEY_STORE_TYPE_P12 = "PKCS12";    privatestaticfinalString SCHEME_HTTPS = "https";    privatestaticfinalintHTTPS_PORT = 8444;        privatestaticfinalString KEY_STORE_CLIENT_PATH = "client.p12";    privatestaticfinalString KEY_STORE_TRUST_PATH = "client.truststore";    privatestaticfinalString KEY_STORE_PASSWORD = "123456";    privatestaticfinalString KEY_STORE_TRUST_PASSWORD = "123456";    privatestaticKeyStore keyStore;    privatestaticKeyStore trustStore;    publicstaticHttpClient getSslHttpClient(Context pContext) {        HttpClient httpsClient = newDefaultHttpClient();        try{            // 服务器端需要验证的客户端证书            keyStore = KeyStore.getInstance(KEY_STORE_TYPE_P12);                        // 客户端信任的服务器端证书            trustStore = KeyStore.getInstance(KEY_STORE_TYPE_BKS);                        InputStream ksIn = pContext.getResources().getAssets().open(KEY_STORE_CLIENT_PATH);            InputStream tsIn = pContext.getResources().getAssets().open(KEY_STORE_TRUST_PATH);            try{                keyStore.load(ksIn, KEY_STORE_PASSWORD.toCharArray());                trustStore.load(tsIn, KEY_STORE_TRUST_PASSWORD.toCharArray());            } catch(Exception e) {                e.printStackTrace();            } finally{                try{                    ksIn.close();                } catch(Exception ignore) {                }                try{                    tsIn.close();                } catch(Exception ignore) {                }            }            SSLSocketFactory socketFactory = newSSLSocketFactory(keyStore, KEY_STORE_PASSWORD, trustStore);            Scheme sch = newScheme(SCHEME_HTTPS, socketFactory, HTTPS_PORT);            httpsClient.getConnectionManager().getSchemeRegistry().register(sch);        } catch(KeyManagementException e) {            e.printStackTrace();        } catch(UnrecoverableKeyException e) {            e.printStackTrace();        } catch(KeyStoreException e) {            e.printStackTrace();        } catch(FileNotFoundException e) {            e.printStackTrace();        } catch(NoSuchAlgorithmException e) {            e.printStackTrace();        } catch(ClientProtocolException e) {            e.printStackTrace();        } catch(IOException e) {            e.printStackTrace();        }        returnhttpsClient;    }} | 
2、android浏览器实现
1.先把你的CA证书拷贝到你的SD卡里面
2.进入手机的"设置"->"位置和安全",最下面有个"从SD卡安装",就是安装证书的。
---------暂时没有实现
基于java的https双向认证,android上亦可用的更多相关文章
- Https双向认证Android客户端配置
		Https .cer证书转换为BKS证书 公式https://blog.csdn.net/zww986736788/article/details/81708967 keytool -importce ... 
- Android Https双向认证 + GRPC
		keywords:android https 双向认证android GRPC https 双向认证 ManagedChannel channel = OkHttpChannelBuilder.for ... 
- 双向认证 HTTPS双向认证
		[微信支付]微信小程序支付开发者文档 https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=4_3 HTTPS双向认证使用说明 ... 
- httpd设置HTTPS双向认证
		去年用tomcat.jboss配置过HTTPS双向认证,那时候主要用的是JDK自带的keytool工具.这次是用httpd + openssl,区别比较大 在网上搜索了很多文章,发现全面介绍的不多,或 ... 
- https双向认证訪问管理后台,採用USBKEY进行系统訪问的身份鉴别,KEY的证书长度大于128位,使用USBKEY登录
		近期项目需求,须要实现用USBKEY识别用户登录,採用https双向认证訪问管理后台管理界面,期间碰到过一些小问题,写出来给大家參考下. 1:前期准备工作 USBKEY 硬件:我买的是飞天诚信 epa ... 
- Keytool配置 Tomcat的HTTPS双向认证
		Keytool配置 Tomcat的HTTPS双向认证 证书生成 keytool 简介 Keytool是一个Java数据证书的管理工具, Keytool将密钥(key)和证书(certificates) ... 
- HTTPS 双向认证构建移动设备安全体系
		HTTPS 双向认证构建移动设备安全体系 对于一些高安全性要求的企业内项目,我们有时希望能够对客户端进行验证.这个时候我们可以使用Https的双向认证机制来实现这个功能. 单向认证:保证server是 ... 
- Tomcat 配置 HTTPS双向认证
		Tomcat 配置 HTTPS 双向认证指引说明: � 本文档仅提供 Linux 操作系统下的指引 � 在阅读本指引前请您在 Linux 部署 JDK 和 Tomcatserver为了 Tomcat ... 
- SpringBoot服务间使用自签名证书实现https双向认证
		SpringBoot服务间使用自签名证书实现https双向认证 以服务server-one和server-two之间使用RestTemplate以https调用为例 一.生成密钥 需要生成server ... 
随机推荐
- 以About Us为范例在Zen cart中增加页面
			1.在includes\languages\english\html_includes目录中新建文件define_about_us.php 2.在includes\templates\Your_tem ... 
- 09 grep、正则表达式和sed
			作业一:整理正则表达式博客 ^ 行首$ 行尾. 除了换行符以外的任意单个字符* 前导字符的零个或多个.* 所有字符[] 字符组内的任一字符[^] 对字符组内的每个字符取反(不匹配字符组内的每个字符)^ ... 
- Java基础知识陷阱(八)
			本文发表于本人博客. 这次我来说说关于&跟&&的区别,大家都知道&是位运算符,而&&是逻辑运算符,看下面代码: public static void m ... 
- java Object转换成指定的类型
			java Object转换成指定的类型 /** * Object转成指定的类型 * @param obj * @param type * @param <T> * @return */ p ... 
- AtCoder Regular Contest 080 C - 4-adjacent
			地址:http://arc080.contest.atcoder.jp/tasks/arc080_a 题目: C - 4-adjacent Time limit : 2sec / Memory lim ... 
- Ubuntu中安装Flask模块
			pip3 list——python3下安装的***** #如果列表没有flask pip3 install flask即可 
- JS正则表达式从入门到入土(2)—— 元字符和字符类
			元字符和字符类 元字符 正则表达式由两种基本字符类型组成: 1.原义(正常)文本字符:代表本身含义的字符,如:a.b.c.1.2.3等. 2.元字符:元字符是在正则表达式中有特殊含义的非字母字符,如\ ... 
- saltstack之keepalived的安装配置
			使用saltstack编译安装keepalived: 创建相应的目录,并在目录下创建相应的sls配置文件 [root@node1 ~]# mkdir /srv/salt/prod/keepalived ... 
- 20145333 《Java程序设计》第5周学习总结
			20145333 <Java程序设计>第5周学习总结 教材学习内容总结 语法与继承架构 使用try.catch Java中所有错误都会被包装成对象,可以尝试(try)执行程序并捕捉(cat ... 
- 20145230熊佳炜《网络对抗》实验八:WEB基础
			20145230熊佳炜<网络对抗>实验八:WEB基础 实验目标 Web前端HTML:能正常安装.启停Apache.理解HTML,理解表单,理解GET与POST方法,编写一个含有表单的HTM ... 
