HttpClient如何访问需要提交客户端证书的SSL服务
1.1 问题背景
自从***一期工程上了CA认证网关之后,在访问受CA认证网关保护的应用子系统时,必须提交客户端证书。那么问题来了,如果是人工(通过IE浏览器)访问子系统自然没问题,访问时会提示选择证书,输入PIN码等等,照做即可。但是如果是应用程序去访问呢?例如,A子系统提供了外部接口程序,由于受到CA认证网关的“保护”,外部程序如何访问A子系统的接口呢?
1.2 问题分析
应用程序自然没法像人工一样,借助浏览器访问应用子系统。此时外部应用程序如果直接通过HttpGet或HttpPost去访问应用子系统的接口时,会抛异常。
由于上了CA认证网关之后,实现的是应用系统访问的双向身份认证,即:客户端须验证服务端的身份,服务端也须验证客户端的身份。为了实现双向身份认证,客户端须安装服务端提供的服务端证书,并且客户端在访问服务端时须提交客户端证书。只有这样才能实现应用系统的正常访问。对于人工访问是如此,对于应用程序访问亦是如此。
令人庆幸的是,ApacheHttpClient提供了基于双向认证机制访问SSL服务的支持。HttpClient通过自定义一个携带证书的SSL连接,实现对需双向认证的服务的访问。
1.3 解决方案
1.3.1 准备工作
结合当前案例的实际情况,有一些准备工作要做:
1、 制作客户端带私钥的软证书,并转化成JKS格式。操作步骤如下:
1)、在用户管理中心注册用户,并推送到证书注册中心;
2)、登录证书注册中心,首先更新用户信息,把证书类型修改为“RSA个人单向证书”(默认是“RSA个人双向证书”);
3)、制作证书,在“签发个人证书”时,“证书设备”选择第二个选项(即:MicrosoftEnhanced Cryptographic Provider v1.0)
4)、导出证书:证书制作完成后就可以在IE的Internet选项-内容-证书列表中看到,然后选中该证书,点击导出。导出过程中注意选择“是,导出私钥(Y)”,如图所示:
然后下一步,输入私钥(123456):
最后导出一个.pfx格式的个人证书:
5)、把pfx格式证书转换为JKS格式(pfx格式的证书无法直接引用,需要转换成keystore格式,JKS就是keystore格式之一)。至于如何转换,百度一下,你就知道。
2、 把服务端证书(证书链)导入trust.keystore中备用。
在本案例中,服务端证书(证书链)包括ROOT.cer和CA.cer。这两个证书须导入trust.keystore。用JDK自带的keytool工具实现导入:
keytool-import -alias Root -file d:/Root.cer -keystore "d:/trust.keystore" -storepass123456
keytool-import -alias CA -file d:/CA.cer -keystore "d:/trust.keystore"-storepass 123456
3、 在网关上添加用户,并授予角色。
针对刚刚制作的证书,所关联的用户需在网关上手动录入,并添加到相应的角色中。只有这样,才能通过CA认证网关的系统级权限验证。操作步骤不再赘述。
1.3.2 访问应用子系统
ApacheHttpClient实现携带证书访问SSL服务的基本原理是:首先加载私钥证书到一个KeyStore中,并把服务端可信任证书加载到一个Trusted KeyStore中;然后用这两个KeyStore构造一个SSLContext对象,最终实例化一个CloseableHttpClient对象,并通过CloseableHttpClient去访问SSL服务。
源码:
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
importjavax.net.ssl.SSLContext;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
/**
*ThisexampledemonstrateshowtocreatesecureconnectionswithacustomSSLcontext.
*/
public class MyClientCustomSSL {
private final static StringTEST_URL ="https://125.35.24.152:446/sfda/HelloWorldServlet";
private final static StringKEYSTORE_FILE ="d:/00000190.jks";
private final static StringTRUSTSTORE_FILE ="d:/trust.keystore";
private final static StringKEYSTORE_PASSWORD ="123456";
public final static void main(String[] args) throws Exception {
//load the CA CERT(private key):
KeyStore keyStore =KeyStore.getInstance(KeyStore.getDefaultType());
FileInputStream instream =
new FileInputStream(new File(KEYSTORE_FILE));
try {
keyStore.load(instream,KEYSTORE_PASSWORD.toCharArray());
} finally {
instream.close();
}
//load the trusted certs:
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
FileInputStream instream1=
new FileInputStream(new File(TRUSTSTORE_FILE));
try {
trustStore.load(instream1,KEYSTORE_PASSWORD.toCharArray());
} finally {
instream1.close();
}
// Trust own CA and allself-signed certs
SSLContext sslcontext= SSLContexts.custom()
.loadKeyMaterial(keyStore,KEYSTORE_PASSWORD.toCharArray())
.loadTrustMaterial(trustStore,new TrustSelfSignedStrategy())
.build();
// Allow TLSv1 protocol only
SSLConnectionSocketFactorysslsf =
new SSLConnectionSocketFactory(sslcontext,
new String[] {"TLSv1" },
null,
SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
CloseableHttpClient httpclient =HttpClients.custom()
.setSSLSocketFactory(sslsf)
.build();
try {
HttpGet httpget = new HttpGet(TEST_URL);
System.out.println("ExecutingRequest:" + httpget.getRequestLine());
CloseableHttpResponseresponse = httpclient.execute(httpget);
try {
HttpEntity entity =response.getEntity();
System.out.println("-------------------------------------");
System.out.println(response.getStatusLine());
System.out.println(EntityUtils.toString(entity));
EntityUtils.consume(entity);
} finally {
response.close();
}
} finally {
httpclient.close();
}
}
}
1.4 附录
1.4.1 HttpClient4.3官方下载
http://hc.apache.org/httpcomponents-client-4.3.x/download.html
1.4.2 官方示例ClientCustomSSL下载
http://hc.apache.org/httpcomponents-client-4.3.x/httpclient/examples/org/apache/http/examples/client/ClientCustomSSL.java
HttpClient如何访问需要提交客户端证书的SSL服务相关推荐
- 如何通过手机客户端Android、Iphone 等访问要求使用客户端证书SSL加密的https网站...
我们在开发手机网站时,对于企业如何想发布加密的只给特定手机访问的网站,那么必须要使用"SSL的客户端证书", 是不是所有的手机系统都对SSL 客户端证书支持得很好呢?我们看看如何使 ...
- java代码实现证书生成客户端证书 实现ssl双向认证
目的:实现web项目的ssl双向认证客户端证书代码生成. 使用openssl生成ca证书和服务端证书,当然也可以通过代码实现 1)创建CA私钥,创建目录ca openssl genrsa -out c ...
- 提交客户端证书_MQTT X v1.3.3 正式发布 - 跨平台 MQTT 5.0 桌面测试客户端
MQTT X 是由全球领先的开源物联网中间件提供商 EMQ 开源的一款跨平台 MQTT 5.0 桌面测试客户端,它支持 macOS,Linux,Windows.MQTT X 的用户界面借助聊天软件的形 ...
- IIS客户端证书访问配置
一. 测试环境配置... 1<?xml:namespace prefix = o /> 1. win2003系统_1.. 1 1.1. ...
- java客户端带证书访问服务端_客户端与服务器SSL双向认证(客户端:java-服务端:java)...
客户端与服务器SSL双向认证(java-java):含源码 (一)实现技术: JSSE(Java Security Socket Extension) 是Sun为了解决在Internet上的实现安全信 ...
- ssl 客户端证书验证_SSL客户端身份验证:这是信任的问题
ssl 客户端证书验证 [编者注:本文介绍了如何为Domino 4.6和4.6.1设置SSL客户机认证.] 互联网上最新的行业流行词是SSL. 但是SSL真正需要提供什么? 安全套接字层(SSL)是一 ...
- SpringBoot的SSL个人CA签发二级证书(动态添加客户端证书)
SpringBoot的SSL个人CA签发二级证书(动态添加客户端证书) 2018年07月10日 17:09:09 得谷养人 阅读数:388 当我们的服务端部署完成运行起来之后,trustStore信任 ...
- 江南天安基于国产密码构建ChinaDRM证书分发云服务
1 引言 近年来,随着4K视频业务的发展及国内版权保护意识的提高,版权方和运营商的版权保护需求日益增长.为满足版权保护生态构建的需求,广电总局科技司于2016年9月批示成立ChinaDRM LAB,专 ...
- iis 使用服务器端证书和客户端证书及访问客户端证书信息
说明:需要先安装"Active Directory证书服务",Windows Server2008R2 在添加角色中选择该"Active Directory证书服务&qu ...
最新文章
- Linux系统开机过程详细分析
- redux和react-redux的使用详解
- python基础之内建函数(二)
- 杭电1232 畅通工程
- 初识Python-1
- linux两台服务器传输,Linux两台服务器之间高速数据传输命令:scp应用详解
- Windows小工具广告弹窗杀手+源码
- cacti更改web登录密码
- 背水一战:苹果向三星采购5G基带芯片遭拒 或自行研发
- mysql 还原 批量ibd_MySQL只有.frm和.ibd文件如何批量恢复InnoDB表-爱可生
- 集备二Linux部署之FTP
- python使用scipy模块from scipy.misc import imread时报错:cannot import name imread问题解决
- 安装 PHP memcached 扩展遇到的3个问题
- 数控切削加工尺寸不稳定怎么办?这么办!
- vivado各个版本百度网盘下载资源(含license(时间到2037年))以及安装流程
- 溯光者:超简单,一文读懂显卡型号编码数字、字母怎么看,都是什么意思?
- 三级网络技术--宽带接入技术--无线接入技术、光纤接入技术
- wamp中php无法启动,wamp无法正常启动
- 分享一个性价比极高的代理IP
- matplotlib.pyplot如何绘制多张子图
热门文章
- Python爬虫入门好学吗?为什么?
- UVA1445 	 Cubist Artwork
- 《正则表达式深入浅出》开放下载,快快收藏!
- android按返回键和Home键都进入后台
- 报错:[Banner] The number of titles and images is different
- 什么叫单模光纤_什么是OS1,OS2的单模光纤
- M1 MacBook的Parellel Desktop(PD)使用问题记录
- 微信小程序不能使用本地图片当背景图片的解决方法
- 微信扫码小绿盒支持支付宝+微信收款教程
- 排序算法-归并排序详细图解