`
sb33060418
  • 浏览: 150100 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

数字证书及安全加密(三)tomcat双向SSL验证及服务调用

阅读更多
本篇博文内容包括:tomcat双向SSL验证配置及使用java程序访问https服务。

系统环境:
windows+jdk1.6.0_31+tomcat6.0+httpclient4.3.1

双向SSL配置
上一篇博文中生成了客户端证书来搭建单项SSL验证,双向SSL就是服务器端也要求客户端使用受信任的证书来访问。

1.生成证书
需要生成客户端证书(含私钥)并将客户端公钥证书导入至服务端信任证书库。

    生成客户端证书
cd %JAVA_HOME%/bin
keytool -genkey -v -alias client -keyalg RSA -storetype PKCS12 -keystore D:/lib/client.p12 -storepass client

创建了别名为server的证书(pcks12类型,含密钥的用户证书交换类型),文件名为client.p12,密码为client,密钥算法为RSA。
生成时需要输入多项证书信息,因不影响本次时间测试,不在此展示。

    导出客户端证书
jdk keytool无法直接导入pcks12类型证书,需要从pcks12证书中导出cer格式证书(公钥证书,才能导入至证书库中
javakeytool -export -v -alias client -keystore D:/lib/client.p12 -storetype PKCS12 -rfc -file D:/lib/client.cer -storepass client

导出了名为client.cer的公钥证书,证书库密码为client

    导入客户端证书至服务端信任库
keytool -import -v -file D:/lib/client.cer -keystore D:/lib/servertrust.keystore -alias client -keypass client -storepass servertrust

客户端公钥证书被导入到了名为servertrust.keystore的证书库中,别名为client,证书密码为client,证书库密码为servertrust。

    查看服务端信任库
keytool -list -v -keystore D:/lib/servertrust.keystore -storepass servertrust

可以看到服务端信任库中包含客户端公钥证书
  • 您的 keystore 包含 1 输入
  • 别名名称: client
  • 创建日期: 2014-1-2
  • 输入类型: trustedCertEntry
  • 所有者:CN=client, OU=client, O=client, L=client, ST=client, C=US

2.配置tomcat
配置conf/server.xml,找到上一篇中配置的
<Connector protocol="org.apache.coyote.http11.Http11NioProtocol" port="8443"></Connector>
标签,将
clientAuth="false"
修改为
clientAuth="true"
使服务端要求验证客户端证书。
在标签中加入服务端信任库属性
truststoreFile="D:/lib/servertrust.keystore" truststorePass="servertrust"

使tomcat信任servertrust.keysto中的公钥证书。

重启tomcat后,访问https://server:8443/发现无法访问,报ssl错误,因为服务端要求客户端证书,而客户端没有对应的证书(含私钥)。

3.导入客户端证书
首先使用浏览器测试客户端证书。

    浏览器客户端导入客户端证书
双击客户端(私钥)证书D:/lib/client.p12,按提示进行操作,即可将客户端证书导入浏览器。
或:打开IE》选项》内容》证书》导入》选择证书类型p12、选择证书》输入客户端证书密码》确认,也可导入客户端证书。
导入客户端证书成功后,可以通过浏览器访问https://server:8443/

    java客户端导入客户端证书
通过jdk访问时报java.net.SocketException: Software caused connection abort: recv failed,也是因为客户端没有受信任的证书。java程序不会导入浏览器中的客户端证书,需要我们手工指定客户端证书。
在上一篇已将服务端公钥证书导入至jdk信任证书库中(客户端信任服务端证书)后,只需要在jvm参数中加入
-Djavax.net.ssl.keyStore=D:/lib/client.p12 -Djavax.net.ssl.keyStoreType=PKCS12 -Djavax.net.ssl.keyStorePassword=client
即在java程序中使用客户端自身的证书,程序即可访问https://server:8443/

4.指定客户端信任库
这里配置中使用的是jdk系统默认的证书库文件,程序中也可以指定使用其他信任证书库文件。

    导入服务端证书至客户端信任库
keytool -import -v -alias server -file D:/lib/server.cer -keystore D:/lib/clienttrust.keystore -keypass server -storepass clienttrust

    查看客户端信任库
keytool -list -v -keystore D:/lib/clienttrust.keystore -storepass clienttrust

    配置客户端信任库
删除jdk默认信任证书库文件"%JAVA_HOME%\jre\lib\security\cacerts",再在jvm参数中加入
-Djavax.net.ssl.trustStore=D:/lib/clienttrust.keystore -Djavax.net.ssl.trustStorePassword=clienttrust -Djavax.net.ssl.trustStoreType=JKS
程序即可使用该jvm访问https。

web应用在服务器启动时,会自动读取jdk默认的证书库来访问https服务。

使用spring security oauth2框架,通过https协议来访问rest服务时,通过上述配置步骤可以验证通过。

5.使用HttpClient访问双向SSL服务
Test类代码如下:
		DefaultHttpClient httpclient = new DefaultHttpClient();
		try {
			System.out.println("---keyStore---");
			KeyStore keyStore = KeyStore.getInstance("PKCS12");
			FileInputStream keyinstream = new FileInputStream(new File(
					"D:/lib/client.p12"));
			try {
				keyStore.load(keyinstream, "client".toCharArray());
			} finally {
				keyinstream.close();
			}
			Enumeration<String> e = keyStore.aliases();
			while (e.hasMoreElements()) {
				System.out.println(e.nextElement());
			}
			System.out.println("---trustStore---");
			KeyStore trustStore = KeyStore.getInstance(KeyStore
					.getDefaultType());
			FileInputStream instream = new FileInputStream(new File(
					"D:/lib/clienttrust.keystore"));
			try {
				trustStore.load(instream, "clienttrust".toCharArray());
			} finally {
				instream.close();
			}
			e = trustStore.aliases();
			while (e.hasMoreElements()) {
				System.out.println(e.nextElement());
			}
			// 可以不指定trustStore,直接使用系统默认位置%JAVA_HOME%\jre\lib\security\cacerts与new
			// SSLSocketFactory(keyStore,"client")
			SSLSocketFactory socketFactory = new SSLSocketFactory(keyStore,
					"client", trustStore);
			Scheme sch = new Scheme("https", socketFactory, 8443);
			httpclient.getConnectionManager().getSchemeRegistry().register(sch);
			HttpGet httpget = new HttpGet(
					"https://server:8443/api/rest/test?access_token=86cb4392-425a-4b30-8e31-7250661a15c4");
			System.out.println("executing request" + httpget.getRequestLine());
			HttpResponse response = httpclient.execute(httpget);
			System.out.println("-------------response-------------");
			System.out.println(response.getStatusLine());
			HttpEntity entity = response.getEntity();
			System.out.println(EntityUtils.toString(response.getEntity()));			if (entity != null) {
				entity.consumeContent();
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		httpclient.getConnectionManager().shutdown();

程序中使用client.p12作为客户端证书(含私钥,公钥证书client.cer已导入服务端信任证书库servertrust.jks),clienttrust.keystore作为客户端信任证书库(含服务端公钥证书server.cer),c/s两端服务器校验都成功后,SSL通道建立完成,即可直接发送信息。
分享到:
评论

相关推荐

    Tomcat 配置SSL完美 https可以正常使用 小程序调用

    Tomcat 配置SSL完美 https可以正常使用 小程序调用Tomcat 配置SSL完美 https可以正常使用 小程序调用Tomcat 配置SSL完美 https可以正常使用 小程序调用

    java开源包1

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    超级有影响力霸气的Java面试题大全文档

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...

    spring security 参考手册中文版

    33.3在Tomcat中设置SSL 254 34.运行认证替换 255 34.1概述 255 34.2配置 255 35. Spring Security加密模块 257 35.1简介 257 35.2加密器 257 35.2.1 BytesEncryptor 257 35.2.2 TextEncryptor 258 35.3关键发电机 ...

    Spring Security 中文教程.pdf

    23.3. 为tomcat配置SSL 24. 替换验证身份 24.1. 概述 24.2. 配置 A. 安全数据库表结构 A.1. User表 A.1.1. 组权限 A.2. 持久登陆(Remember-Me)表 A.3. ACL表 A.3.1. Hypersonic SQL A.3.1.1. ...

    java 面试题 总结

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...

    SpringSecurity 3.0.1.RELEASE.CHM

    22.3. 为tomcat配置SSL 23. 替换验证身份 23.1. 概述 23.2. 配置 A. 安全数据库表结构 A.1. User表 A.1.1. 组权限 A.2. 持久登陆(Remember-Me)表 A.3. ACL表 A.3.1. Hypersonic SQL A.3.1.1. PostgreSQL...

    JAVA上百实例源码以及开源项目源代码

     数字证书:从文件中读取数字证书,生成文件输入流,输入文件为c:/mycert.cer,获取一个处理X.509证书的证书工厂…… Java+ajax写的登录实例 1个目标文件 内容索引:Java源码,初学实例,ajax,登录  一个Java+ajax写...

    Spring Security-3.0.1中文官方文档(翻译版)

    23.3. 为tomcat 配置SSL 24. 替换验证身份 24.1. 概述 24.2. 配置 A. 安全数据库表结构 A.1. User 表 A.1.1. 组权限 A.2. 持久登陆(Remember-Me)表 A.3. ACL 表 A.3.1. Hypersonic SQL A....

    JAVA上百实例源码以及开源项目

     数字证书:从文件中读取数字证书,生成文件输入流,输入文件为c:/mycert.cer,获取一个处理X.509证书的证书工厂…… Java+ajax写的登录实例 1个目标文件 内容索引:Java源码,初学实例,ajax,登录  一个Java+ajax写...

    java开源包11

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包2

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包3

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包6

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包5

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包10

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包4

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包8

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包7

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

Global site tag (gtag.js) - Google Analytics