`
jxguoyan
  • 浏览: 14517 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

JSSE访问带有未验证证书的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的安全性,但需要手工导入证书;第二种方法虽然不用手工导入证书,但需要小心使用,否则会带来一些安全隐患。
分享到:
评论

相关推荐

    用jsse定制SSL

    **JSSE(Java Secure Socket Extension)是Java平台中用于实现安全网络通信的API,它提供了SSL(Secure Sockets Layer)和TLS(Transport Layer Security)协议的实现,使得开发者能够构建安全的HTTPS、SMTPS等服务...

    tomcat,https加密方式(jsse.openssl)

    ### Tomcat HTTPS 加密配置详解 ...综上所述,无论是使用 JSSE 还是 OpenSSL 来配置 Tomcat 的 HTTPS 加密,都需要生成证书、配置 Tomcat 以及可能的其他相关设置。选择哪种方法取决于具体的场景需求和个人偏好。

    为高级 JSSE 开发人员定制 SSL

    2. **KeyManagers和TrustManagers**:JSSE中的KeyManager处理密钥和证书的选择,而TrustManager负责验证连接对方的证书。开发者可以通过自定义KeyManager和TrustManager的实现来定制SSL连接的行为,例如动态选择证书...

    jsse.jar

    jsse.jar

    jsse-2.0.5.jar.zip

    java.security.NoSuchAlgorithmException: SHA1PRNG SecureRandom not available at sun.security.jca.GetInstance.getInstance(GetInstance.java:142) at java.security....unpack200 jsse.pack jsse.jar

    Java如何跳过https的ssl证书验证详解

    在针对http进行升级时,在HTTPS的证书未经权威机构认证的情况下,访问HTTPS站点的两种方法:一种方法是把该证书导入到Java的TrustStore文件中,另一种是自己实现并覆盖JSSE缺省的证书信任管理器类。 五、Java获取...

    jsse.jar 用于jsse.jar

    jar网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|版权声明|问题报告

    jsse-samples-guides.zip

    如果证书未被信任,TrustManager会抛出异常。 3. **SSLContext**:JSSE中的核心类,用于配置KeyManager和TrustManager,并创建SSLSocketFactory或SSLServerSocketFactory。 4. **SSLSocket和SSLServerSocket**:...

    用JSSE定制SSL连接.docx

    KeyStore用于存储私钥和证书链,是客户端或服务器身份验证的基础。 - **客户端KeyStore**:包含客户端的私钥及其对应的公钥证书。 - **服务器端KeyStore**:包含服务器的私钥及其对应的公钥证书。 ##### Trust...

    jsse工具包.rar

    JAR(Java Archive,Java 归档文件)是与平台无关的文件格式,它允许将许多文件组合成一个压缩文件。为 J2EE 应用程序创建的 JAR 文件是 EAR 文件(企业 JAR 文件)。JAR 文件格式以流行的 ZIP 文件格式为基础。...

    java client访问https server(客户端代码、服务器端配置)

    8. 错误处理:在实际应用中,可能出现各种SSL/TLS相关的异常,如证书未信任、证书过期等,需要适当的错误处理机制来处理这些问题,例如捕获`SSLHandshakeException`并给出明确的提示。 总之,Java客户端访问HTTPS...

    jre包jsse.jar jce.jar dnsns.jar charsets.jar的源码

    主要是在源码网站上抓取的jsse.jar jce.jar dnsns.jar charsets.jar源代码。 其中附上抓取的源代码,可以自己修改相应的参数,实现自定义下载。 因为写的匆忙,因此没有加上多线程,欢迎修改交流。

    直接通过Socket使用JSSE

    在生产环境中,应该使用标准的信任管理器并处理证书验证。 总结一下,通过Java的JSSE,我们可以直接使用Socket建立HTTPS连接,步骤包括:配置SSLContext、创建HttpsURLConnection、设置SocketFactory和读取响应。这...

    jsp-api-2.1.jar+servlet-api-2.5-6.1.9.jar+jsse.jar

    开发者可以使用JSSE来建立安全的HTTPS连接,进行数字证书管理,以及进行加密和签名操作。这对于开发需要处理敏感信息,如网上银行、电子商务等应用来说,是必不可少的。 这三者结合在一起,通常用于搭建或运行基于...

    大宝CA版本的国密SSL规范实现,JSSE,1.0.1版本,含通信示例代码

    使用方法见:...1. 修改了前一版本中证书验证的bug,支持JDK8的高版本 2. 适配了一些硬件设备和国密浏览器 3. 支持国密SSL双向认证 4. 将过期的国密证书替换为新证书

    CA证书开发 JAR包 API

    在IT行业中,尤其是在网络安全和身份验证领域,CA(Certificate Authority)证书扮演着至关重要的角色。CA证书是数字证书的一种,由可信任的第三方机构签发,用于确认网络实体的身份。在Java开发中,处理和管理这些...

    wcf x.509证书认证

    9. **互操作性**: WCF的X.509证书认证功能也支持与其他平台(如Java的JSSE或HTTPS)的互操作,这对于跨平台的通信非常重要。 总结来说,这个压缩包提供的示例可能包含了一个完整的WCF服务和客户端,它们使用X.509...

    调用https格式的webservice jar包。

    当我们谈论“调用HTTPS格式的Web Service”时,我们实际上是指通过安全的HTTPS协议来访问和使用Web Service。HTTPS(HyperText Transfer Protocol Secure)是HTTP的安全版本,它利用SSL/TLS协议对传输的数据进行加密...

    java 实现数字证书的操作实现网络安全

    Java 数字证书操作是网络安全领域中的重要组成部分,主要用于身份验证和数据加密,确保网络通信的安全。在Java中,我们可以利用Java Cryptography Extension (JCE) 和 Java Secure Socket Extension (JSSE) 这些强大...

Global site tag (gtag.js) - Google Analytics