文档章节

通过JSSE来发起Https请求

阿山du
 阿山du
发布于 2013/12/03 18:06
字数 2309
阅读 275
收藏 7
点赞 0
评论 0

    工作中会遇到https请求和接受相关的问题,这篇文章介绍的挺不错,转来记录一下,抽时间还会在这篇文章的基础上增加一些自己理解的东东。

    摘 要

    JSSE是一个SSL和TLS的纯Java实现,通过JSSE可以很容易地编程实现对HTTPS站点的访问。但是,如果该站点的证书未经权威机构的验证,JSSE将拒绝信任该证书从而不能访问HTTPS站点。本文在简要介绍JSSE的基础上提出了两种解决该问题的方法。


   引言

  过去的十几年,网络上已经积累了大量的Web应用。如今,无论是整合原有的Web应用系统,还是进行新的Web开发,都要求通过编程来访问某些Web页面。传统的方法是使用Socket接口,但现在很多开发平台或工具如.NET、Java或PHP等都提供了简单的Web访问接口,使用这些接口很容易编程实现与Web应用系统的交互访问,即使要访问那些采用了HTTPS而不是HTTP的Web应用系统。

  HTTPS,即安全的超文本传输协议,采用了SSL技术,被广泛使用以保证Web应用系统的安全性。访问Web应用的编程接口大多封装了SSL,使得访问HTTPS和访问HTTP一样简单。但是很多中、小型应用系统或基于局域网、校园网的应用系统所使用的证书并不是由权威的认证机构发行或者被其验证,直接使用这些编程接口将不能访问HTTPS。

  本文将在简要介绍JSSE的基础上,详细描述使用JSSE访问HTTPS的方法,主要说明了如何访问带有未经验证证书的HTTPS站点。

   JSSE简介

  Java安全套接扩展 (Java Secure Socket Extension, JSSE)是实现Internet安全通信的一系列包的集合。它是一个SSL和TLS的纯Java实现,可以透明地提供数据加密、服务器认证、信息完整性等功能,可以使我们像使用普通的套接字一样使用JSSE建立的安全套接字。JSSE是一个开放的标准,不只是Sun公司才能实现一个JSSE,事实上其他公司有自己实现的JSSE。

  在深入了解JSSE之前,需要了解一个有关Java安全的概念:客户端的TrustStore文件。客户端的TrustStore文件中保存着被客户端所信任的服务器的证书信息。客户端在进行SSL连接时,JSSE将根据这个文件中的证书决定是否信任服务器端的证书。

  JSSE中,有一个信任管理器类负责决定是否信任远端的证书,这个类有如下的处理规则:

  ⑴ 果系统属性javax.net.sll.trustStore指定了TrustStore文件,那么信任管理器就去jre安装路径下的lib/security/目录中寻找并使用这个文件来检查证书。

  ⑵ 果该系统属性没有指定TrustStore文件,它就会去jre安装路径下寻找默认的TrustStore文件,这个文件的相对路径为:lib/security/jssecacerts。

  ⑶ 如果 jssecacerts不存在,但是cacerts存在(它随J2SDK一起发行,含有数量有限的可信任的基本证书),那么这个默认的TrustStore文件就是cacerts。

  直接使用类HttpsURLConnection访问Web页面

  Java提供了一种非常简洁的方法来访问HTTPS网页,即使用类HttpsURLConnection、URL等。这几个类为支持HTTPS对JSSE相关类做了进一步的封装,例子如下所示:

            URL reqURL = new URL("https://www.sun.com" ); //创建URL对象
            HttpsURLConnection httpsConn = (HttpsURLConnection)reqURL.openConnection();

        /*下面这段代码实现向Web页面发送数据,实现与网页的交互访问
           httpsConn.setDoOutput(true); 
            OutputStreamWriter out = new OutputStreamWriter(huc.getOutputStream(), "8859_1"); 
            out.write( "……" ); 
            out.flush(); 
            out.close();
        */

        //取得该连接的输入流,以读取响应内容 
           InputStreamReader insr = new InputStreamReader(httpsConn.getInputStream();

        //读取服务器的响应内容并显示
            int respInt = insr.read();
            while( respInt != -1){
                 System.out.print((char)respInt);
                 respInt = insr.read();
               }
  这段代码能够正常执行,然而把访问的URL改为https://login.bjut.edu.cn时,程序将抛出异常javax.net.ssl.SSLException,这是由于https://login.bjut.edu.cn站点的安全证书不被JSSE所信任。根据JSSE简介中对信任管理器的分析,一种解决这个问题的方法是按照信任管理器的处理规则,把站点的证书放到证书库文件jssecacerts中,或者把证书存放到任一TrustStore文件中,然后设置系统属性javax.net.sll.trustStore指向该文件。另一种解决方法则是自己实现信任管理器类,让它信任我们指定的证书。下面分别介绍这两种方法。

   将证书导入到TrustStore文件中

  Java提供了命令行工具keytool用于创建证书或者把证书从其它文件中导入到Java自己的TrustStore文件中。把证书从其它文件导入到TrustStore文件中的命令行格式为:

  keytool -import -file src_cer_file –keystore dest_cer_store

  其中,src_cer_file为存有证书信息的源文件名,dest_cer_store为目标TrustStore文件。

  在使用keytool之前,首先要取得源证书文件,这个源文件可使用IE浏览器获得,IE浏览器会把访问过的HTTPS站点的证书保存到本地。从IE浏览器导出证书的方法是打开“Internet 选项”,选择“内容”选项卡,点击“证书…”按钮,在打开的证书对话框中,选中一个证书,然后点击“导出…”按钮,按提示一步步将该证书保存到一文件中。最后就可利用keytool把该证书导入到Java的TrustStore文件中。为了能使Java程序找到该文件,应该把这个文件复制到jre安装路径下的lib/security/目录中。

  这样,只需在程序中设置系统属性javax.net.sll.trustStore指向文件dest_cer_store,就能使JSSE信任该证书,从而使程序可以访问使用未经验证的证书的HTTPS站点。

  使用这种方法,编程非常简单,但需要手工导出服务器的证书。当服务器证书经常变化时,就需要经常进行手工导出证书的操作。下面介绍的实现X509证书信任管理器类的方法将避免手工导出证书的问题。

X509证书信任管理器类的实现及应用

  在JSSE中,证书信任管理器类就是实现了接口X509TrustManager的类。我们可以自己实现该接口,让它信任我们指定的证书。

  接口X509TrustManager有下述三个公有的方法需要我们实现:

  ⑴ oid checkClientTrusted(X509Certificate[] chain, String authType) 
throws CertificateException

  该方法检查客户端的证书,若不信任该证书则抛出异常。由于我们不需要对客户端进行认证,因此我们只需要执行默认的信任管理器的这个方法。JSSE中,默认的信任管理器类为TrustManager。

  ⑵ oid checkServerTrusted(X509Certificate[] chain, String authType) 
throws CertificateException 

  该方法检查服务器的证书,若不信任该证书同样抛出异常。通过自己实现该方法,可以使之信任我们指定的任何证书。在实现该方法时,也可以简单的不做任何处理,即一个空的函数体,由于不会抛出异常,它就会信任任何证书。

  ⑶ X509Certificate[] getAcceptedIssuers() 

  返回受信任的X509证书数组。

  自己实现了信任管理器类,如何使用呢?类HttpsURLConnection似乎并没有提供方法设置信任管理器。其实,HttpsURLConnection通过SSLSocket来建立与HTTPS的安全连接,SSLSocket对象是由SSLSocketFactory生成的。HttpsURLConnection提供了方法setSSLSocketFactory(SSLSocketFactory)设置它使用的SSLSocketFactory对象。SSLSocketFactory通过SSLContext对象来获得,在初始化SSLContext对象时,可指定信任管理器对象。下面用一个图简单表示这几个JSSE类的关系: 

                    
                        图1 部分JSSE类的关系图
  假设自己实现的X509TrustManager类的类名为:MyX509TrustManager,下面的代码片断说明了如何使用MyX509TrustManager:

    //创建SSLContext对象,并使用我们指定的信任管理器初始化
        TrustManager[] tm = {new MyX509TrustManager ()}; 
        SSLContext sslContext = SSLContext.getInstance("SSL","SunJSSE"); 
        sslContext.init(null, tm, new java.security.SecureRandom()); 

    //从上述SSLContext对象中得到SSLSocketFactory对象
        SSLSocketFactory ssf = sslContext.getSocketFactory();

    //创建HttpsURLConnection对象,并设置其SSLSocketFactory对象
        HttpsURLConnection httpsConn = (HttpsURLConnection)myURL.openConnection();
        httpsConn.setSSLSocketFactory(ssf);
  这样,HttpsURLConnection对象就可以正常连接HTTPS了,无论其证书是否经权威机构的验证,只要实现了接口X509TrustManager的类MyX509TrustManager信任该证书。

  小结

  本文主要介绍了在HTTPS的证书未经权威机构认证的情况下,访问HTTPS站点的两种方法,一种方法是把该证书导入到Java的TrustStore文件中,另一种是自己实现并覆盖JSSE缺省的证书信任管理器类。两种方法各有优缺点,第一种方法不会影响JSSE的安全性,但需要手工导入证书;第二种方法虽然不用手工导入证书,但需要小心使用,否则会带来一些安全隐患。

本文转载自:http://tech.163.com/06/0406/09/2E11A15U0009159T.html

共有 人打赏支持
阿山du
粉丝 0
博文 11
码字总数 7555
作品 0
东城
程序员
HttpClient及有关jar包详解

1.HttpClient简介 HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。本...

长平狐
2012/11/12
12.2K
2
httpclient 无信任证书直接使用https含项目demo

说下HTPPS: HTTPS,即安全的超文本传输协议,采用了SSL技术,被广泛使用以保证Web应用系统的安全性。访问Web应用的编程接口大多封装了SSL,使得访问HTTPS和访问HTTP一样简单。但是很多中、小...

小风89
2016/09/02
38
0
HTTPS的证书未经权威机构认证的情况下,访问HTTPS站点的两种方法

注意一下文章中提到的jsse在jdk1.4以后已经集成了,不必纠结. 摘 要 JSSE是一个SSL和TLS的纯Java实现,通过JSSE可以很容易地编程实现对HTTPS站点的访问。但是,如果该站点的证书未经权威机构的...

swearyd457
2015/08/18
0
0
HTTPS 信任证书

类代码 调用方式 在web应用交互过程中,有很多场景需要保证通信数据的安全;在前面也有好多篇文章介绍了在Web Service调用过程中用WS-Security来保证接口交互过程的安全性,值得注意的是,该...

文艺小青年
2017/06/08
0
0
收藏 - Java 安全套接字扩展 (JSSE) 参考指南

原文地址: https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html?spm=a2c4e.11153940.blogcont324371.10.68b578d3G07OBO 中英文对照: https://www.mic......

洋葱曲奇饼干
04/29
0
0
Spring 跨域支持(CROS)注解:@CrossOrigin

Spring MVC 4.2 增加 CORS 支持 跨站 HTTP 请求(Cross-site HTTP request)是指发起请求的资源所在域不同于该请求所指向资源所在的域的 HTTP 请求。比如说,域名A(http://domaina.example)的某...

孟飞阳
2017/11/08
0
0
SSO单点登录、跨域重定向、跨域设置Cookie、京东单点登录实例分析

最近在研究SSO单点登录技术,其中有一种就是通过js的跨域设置cookie来达到单点登录目的的,下面就已京东商城为例来解释下跨域设置cookie的过程 涉及的关键知识点: 1、jQuery ajax跨域重定向...

bengozhong
2016/08/15
33
0
Java安全通信:HTTPS与SSL

HTTPS概念 1)简介 HTTPS(全称:Hypertext Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因...

亭子happy
2013/06/19
0
0
OkHttp3.7缓存原理分析

学习自https://yq.aliyun.com/articles/78102?spm=a2c4e.11153940.blogcont78105.14.785137beBUL1wW 温馨提示 在熟练掌握HTTP协议后,会看起来很舒服,因为就是HTTP协议的东西在Andorid中的实...

qq_36523667
04/17
0
0
Spring MVC 4.2 增加 CORS 支持

标签: spring mvc / cors / 跨越资源共享 30238 Spring MVC 4.2 增加 CORS 支持 跨站 HTTP 请求(Cross-site HTTP request)是指发起请求的资源所在域不同于该请求所指向资源所在的域的 HTTP...

费氏家族
2017/11/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

设计模式:单例模式

单例模式的定义是确保某个类在任何情况下都只有一个实例,并且需要提供一个全局的访问点供调用者访问该实例的一种模式。 实现以上模式基于以下必须遵守的两点: 1.构造方法私有化 2.提供一个...

人觉非常君
6分钟前
0
0
《Linux Perf Master》Edition 0.4 发布

在线阅读:https://riboseyim.gitbook.io/perf 在线阅读:https://www.gitbook.com/book/riboseyim/linux-perf-master/details 百度网盘【pdf、mobi、ePub】:https://pan.baidu.com/s/1C20T......

RiboseYim
17分钟前
0
0
conda 换源

https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/conda config --add channels https://mir......

阿豪boy
27分钟前
0
0
Confluence 6 安装补丁类文件

Atlassian 支持或者 Atlassian 缺陷修复小组可能针对有一些关键问题会提供补丁来解决这些问题,但是这些问题还没有放到下一个更新版本中。这些问题将会使用 Class 类文件同时在官方 Jira bug...

honeymose
36分钟前
0
0
非常实用的IDEA插件之总结

1、Alibaba Java Coding Guidelines 经过247天的持续研发,阿里巴巴于10月14日在杭州云栖大会上,正式发布众所期待的《阿里巴巴Java开发规约》扫描插件!该插件由阿里巴巴P3C项目组研发。P3C...

Gibbons
45分钟前
0
0
Tomcat介绍,安装jdk,安装tomcat,配置Tomcat监听80端口

Tomcat介绍 Tomcat是Apache软件基金会(Apache Software Foundation)的Jakarta项目中的一个核心项目,由Apache、Sun和其他一些公司及个人共同开发而成。 java程序写的网站用tomcat+jdk来运行...

TaoXu
45分钟前
0
0
TensorFlow,从一个 Android Demo 开始

TensorFlow Android Demo 项目地址 Machine Learning 既然提到了 TensorFlow,那是不是得神经网络、机器学习了解下? 如果你能坚持把 机器学习速成课程 给啃完了,觉得还挺有兴趣的,那可以考...

孟飞阳
47分钟前
0
0
JVM学习笔记二:内存结构规范

1、JVM基本结构图 2、java堆(Heap) 3、方法区(Method Area) 4、程序计数器 5、JAVA栈图解 局部变量表:八大基本类型,还可以存储引用类型 上一篇:JVM学习笔记一:类加载机制介绍...

刘祖鹏
52分钟前
0
0
mui集成微信H5支付(返回白屏问题已经解决)

一.项目需求 因为公司人员缺少,没有专门开发安卓和ios的人员,为了项目尽早上线采用了混合APP开发的方式,我选择了MUI混合开发框架,项目中需要在用户购买VIP会员的时候进行支付,所以需要在项目...

银装素裹
56分钟前
1
0
SpringBoot集成Redis--配置自定义的RedisCacheManager

配置自定义的RedisCacheManager--1自定义键生成规则 默认的键生成器 当不指定缓存的key时,SpringBoot会使用SimpleKeyGenerator生成key。 SimpleKeyGenerator SimpleKey 查看源码可以发现,它...

karma123
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部