Internet 安全编程(信任管理器,HttpsURLConnection ...)

 

既然 QBrowser 使用 URL 类,它就可以处理 HTTP HTTPS 请求。你可以使用 HTTP HTTPS 地址测试

 
QBrowser 。这里是一些测试:

1、请求 http://www.javacourses.com,你会看到如图 1 所示的内容。

 

1http://www.javacourses.com

2、请求 https://www.jam.ca,结果抛出了异常。因为这个网页服务器的证书不受信任并且不能在默认页中找到,所以它抛出如图 2 所示的异常。

 

2https://www.jam.ca

3、请求 https://localhost,这里运行着第一部分中写的 HttpServer。注意,如果你使用命令 java QBrowser 来运行 QBrowser,而服务器的证书导出后被导入默认文件 jssecacerts,那么应该将该文件拷贝到 java.home 目录的 lib/security 子目录中。如果证书被导入了其它文件,你可以使用 trustStore 选项,如:java -Djavax.net.ssl.trustStore=file QBrowser。使用其实任何一种方法,都会工作,并且你可以看到如图浏览器 3 所示的默认页面。

 

3https://localhost

HttpsURLConnection

这个类存在于 javax.net.ssl 包中,它扩展了 java.net.HttpURLConnection,以支持 HTTPS 描述的一些特性。它能够通过 SSL/TLS 套接字建立安全通道来请求/获取数据。示例代码 4 展示了一个小型客户端,它使用 HttpsURLConnection 类从 HTTPS 服务器下载文档。

示例代码 4ReadHttpsURL3.java

import java.io.*;

import java.net.*;

import javax.net.ssl.*;

public class ReadHttpsURL3 {

    public static void main(String[] argv) throws Exception {

        URL url = new URL(argv[0]);

        HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();

        connection.setDoOutput(true);

        BufferedReader in

            = new BufferedReader(new InputStreamReader(connection.getInputStream()));

        String line;

        while ((line = in.readLine()) != null) {

            System.out.println(line);

        }

        in.close();

    }

}

现在试试 ReadHttpsURL3,完成上面讨论的内容。注意,无论如何,既然我们使用 URL 类,你就能在命令行指定 URL,包括协议的名称。这里是一个例子:

Prompt> java ReadHttpsURL3 https://www.sun.com

HttpsURLConnection 有一个非常有趣的特点:一旦获得了连接,你就可以在网络连接之前使用一些有用的参数对其进行配置,如 HostnameVerifierHostnameVerifier 是一个接口,它申明了方法:public boolean verify (String hostname, SSLSession session)。而且,它像下面所述的那样工作:

l         如果 SSL/TLS 标准主机名校验逻辑失败,执行过程中会调用回调类的 verify 方法。回调类是实现了 HostnameVerifier 接口的类。

l         如果回调类检查到主机名可以接受,则允许连接,否则,连接会被终止。

回调类遵循的规则即可以是基本的验证方法,也可以依赖其它验证方法。这里说明了如何实现:

public class MyVerified implements HostnameVerifier {

    public boolean verify(String hostname, SSLSession session) {

        // pop up a dialog box

        // ...

        // return either true or false

    }

}

现在,可以这样使用它:

HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();

connection.setHostnameVerifier(new MyVerifier());

信任管理器

一个 SSL 客户端,如网页浏览器,连接到 SSL 服务器 ( HTTPS 服务器) 的时候,HTTPS 服务器将自己的证书链交给客户端验证。SSL 规范规定,如果在证书链中发现有无效的证书,客户端应该立即终止连接。一些网页浏览器,如 Netscape Communicator Microsoft Internet Explorer,询问用户是否忽略无效的证书并继续检查证书链,以确定是否有可能验证通过 HTTPS 服务器。使用 javax.net.sll.TrustManager 可以很好的消除这种矛盾,它是 JSSE 信任管理器的基础接口。而这些信任管理器则是用来管理可信任的资料以及决定是否接受某个凭证的。典型的信任管理器都支持基于 X.509 的证书,它是 J2DK keytool 可以管理的一个普通的证书格式。

X509TrustManager 接口

javax.net.sll.X509TrustManager 接口扩展了普通的 TrustManager 接口。使用基于 X.509 公钥证书验证方案时,信任管理器必须实现该接口。实现 X509TrustManager 可以创建信任管理器。这里有一个空实现:

public class MyTrustManager implements X509TrustManager {

    MyTrustManager() { // constructor

        // create/load keystore

    }

     public void checkClientTrusted(X509Certificate chain[], String authType)

        throws CertificatException {

    }

     public void checkServerTrusted(X509Certificate chain[], String authType)

        throws CertificationException {

        // special handling such as poping dialog boxes

    }

    public X509Certificate[] getAcceptedIssuers() {

    }

}

为了支持远端套接字 X.509 证书,实现了 X509TrustManager 接口的类,其实例要传递给 SSLContext 对象的 init 方法。它作为 SSL 套接字工厂。换句话说,一旦创建了信任管理器且通过 init 方法将其分配给了一个 SSLSocket,以后从 SSLContext 创建的 SocketFactories 在作信任决策时将使用新的信任管理器。下面的代码段就是个示例:

X509TrustManager xtm = new MyTrustManager()

TrustManager mytm[] = {xtm};

SSLContext ctx = SSLContext.getInstance("SSL");

ctx.init(null,mytm, null );

SSLSocketFactory sf = ctx.getSocketFactory();

JSSE 调试工具

Sun JSSE 实现提供了动态调试跟踪支持,使用系统属性 javax.net.debug 即可。JSSE 并不正式支持这个特性,但它可以让你看到在 SSL 通信过程中幕后在干什么。这个工具可以通过如下命令使用:

Prompt> java -Djavax.net.debug=option[debugSpecifiers] MySSLApp

如果你使用了 help 参数,它就会显示调试选项列表。J2SE 1.4.1 中,选项如下:

all            turn on all debugging

ssl            turn on ssl debugging

The following can be used with ssl:

        record       enable per-record tracing

        handshake    print each handshake message

        keygen       print key generation data

        session      print session activity

        defaultctx   print default SSL initialization

        sslctx       print SSLContext tracing

        sessioncache print session cache tracing

        keymanager   print key manager tracing

        trustmanager print trust manager tracing

 

        handshake debugging can be widened with:

        data         hex dump of each handshake message

        verbose      verbose handshake message printing

 

        record debugging can be widened with:

        plaintext    hex dump of record plaintext

你必须指定参数 ssl 或者 all 中的一个,紧跟 debug 符号。可以使用一个或多个调试说明符,使用“:”或者“,”作为分隔符。说明符不是必须的,但可以增强可读性。这里是一些例子:

Prompt> java -Djavax.net.debug=all MyApp

Prompt> java -Djavax.net.debug=ssl MyApp

Prompt> java -Djavax.net.debug=ssl:handshake:trustmanager MyApp

总结

这篇文章展示了如何使用 JSSE (SSL 协议的框架和实现) 开发安全的客户端应用程序。这篇文章中的例子展示了将 SSL 整合到 C/S 应用程序是多么简单的事情。这篇文章中讲到一个网页浏览器,QBrowser,可以处理 HTTP HTTPS 请求。

QBrowser 中,如果服务器上,按输入 HTTPS 的地址中不存在有效的证书,则会抛出一个异常。你也许想修改 QBrowser 使其能够处理这个异常并且弹出一个窗口询问用户是否愿意下载安装证书,那么你可以把它做为一个练习。1.4.x Java 插件使用了 JSSE,它有自己的的信任管理器,如果它不能在信任库里找到证书,而弹出窗口提示。

------------------------------------------------------------------

原文:Secure Internet Programming with Java 2, Standard Edition (J2SE) 1.4 (Part II: The Client Side)

参阅:Secure Internet Programming with Java 2, Standard Edition (J2SE) 1.4 (Part I: The Server Side)

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值