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服务相关推荐

  1. 如何通过手机客户端Android、Iphone 等访问要求使用客户端证书SSL加密的https网站...

    我们在开发手机网站时,对于企业如何想发布加密的只给特定手机访问的网站,那么必须要使用"SSL的客户端证书", 是不是所有的手机系统都对SSL 客户端证书支持得很好呢?我们看看如何使 ...

  2. java代码实现证书生成客户端证书 实现ssl双向认证

    目的:实现web项目的ssl双向认证客户端证书代码生成. 使用openssl生成ca证书和服务端证书,当然也可以通过代码实现 1)创建CA私钥,创建目录ca openssl genrsa -out c ...

  3. 提交客户端证书_MQTT X v1.3.3 正式发布 - 跨平台 MQTT 5.0 桌面测试客户端

    MQTT X 是由全球领先的开源物联网中间件提供商 EMQ 开源的一款跨平台 MQTT 5.0 桌面测试客户端,它支持 macOS,Linux,Windows.MQTT X 的用户界面借助聊天软件的形 ...

  4. IIS客户端证书访问配置

    一.         测试环境配置... 1<?xml:namespace prefix = o /> 1.           win2003系统_1.. 1 1.1.         ...

  5. java客户端带证书访问服务端_客户端与服务器SSL双向认证(客户端:java-服务端:java)...

    客户端与服务器SSL双向认证(java-java):含源码 (一)实现技术: JSSE(Java Security Socket Extension) 是Sun为了解决在Internet上的实现安全信 ...

  6. ssl 客户端证书验证_SSL客户端身份验证:这是信任的问题

    ssl 客户端证书验证 [编者注:本文介绍了如何为Domino 4.6和4.6.1设置SSL客户机认证.] 互联网上最新的行业流行词是SSL. 但是SSL真正需要提供什么? 安全套接字层(SSL)是一 ...

  7. SpringBoot的SSL个人CA签发二级证书(动态添加客户端证书)

    SpringBoot的SSL个人CA签发二级证书(动态添加客户端证书) 2018年07月10日 17:09:09 得谷养人 阅读数:388 当我们的服务端部署完成运行起来之后,trustStore信任 ...

  8. 江南天安基于国产密码构建ChinaDRM证书分发云服务

    1 引言 近年来,随着4K视频业务的发展及国内版权保护意识的提高,版权方和运营商的版权保护需求日益增长.为满足版权保护生态构建的需求,广电总局科技司于2016年9月批示成立ChinaDRM LAB,专 ...

  9. iis 使用服务器端证书和客户端证书及访问客户端证书信息

    说明:需要先安装"Active Directory证书服务",Windows Server2008R2 在添加角色中选择该"Active Directory证书服务&qu ...

最新文章

  1. Linux系统开机过程详细分析
  2. redux和react-redux的使用详解
  3. python基础之内建函数(二)
  4. 杭电1232 畅通工程
  5. 初识Python-1
  6. linux两台服务器传输,Linux两台服务器之间高速数据传输命令:scp应用详解
  7. Windows小工具广告弹窗杀手+源码
  8. cacti更改web登录密码
  9. 背水一战:苹果向三星采购5G基带芯片遭拒 或自行研发
  10. mysql 还原 批量ibd_MySQL只有.frm和.ibd文件如何批量恢复InnoDB表-爱可生
  11. 集备二Linux部署之FTP
  12. python使用scipy模块from scipy.misc import imread时报错:cannot import name imread问题解决
  13. 安装 PHP memcached 扩展遇到的3个问题
  14. 数控切削加工尺寸不稳定怎么办?这么办!
  15. vivado各个版本百度网盘下载资源(含license(时间到2037年))以及安装流程
  16. 溯光者:超简单,一文读懂显卡型号编码数字、字母怎么看,都是什么意思?
  17. 三级网络技术--宽带接入技术--无线接入技术、光纤接入技术
  18. wamp中php无法启动,wamp无法正常启动
  19. 分享一个性价比极高的代理IP
  20. matplotlib.pyplot如何绘制多张子图

热门文章

  1. Python爬虫入门好学吗?为什么?
  2. UVA1445 Cubist Artwork
  3. 《正则表达式深入浅出》开放下载,快快收藏!
  4. android按返回键和Home键都进入后台
  5. 报错:[Banner] The number of titles and images is different
  6. 什么叫单模光纤_什么是OS1,OS2的单模光纤
  7. M1 MacBook的Parellel Desktop(PD)使用问题记录
  8. 微信小程序不能使用本地图片当背景图片的解决方法
  9. 微信扫码小绿盒支持支付宝+微信收款教程
  10. 排序算法-归并排序详细图解