第二部分客户端
Java 安全套接扩展 (Java Secure Socket Extension JSSE) 使 Internet 安全通信成为现实它是 SSL (Secure Socket Layer) 及 TLS (Transport Layer Security由 SSL 改善而来) 的框架和实现这个包让 Java 开发人员能够开发安全的网络应用为基于 TCP/IP 的何应用协议如 HTTPFTPTelnet或者 NTTP在客户端和服务器端之间建立安全的数据通道
在这篇文章的第一部分 (服务器端)作者已经详细说明了 SSL 和 JSSE并且说明了如何开发服务器端支持 SSL 应用程序那一部分中我们开发了一个 HTTPS 服务器这是一个非常有用的应用程序在这一部分中同样会用到它
在这篇文章涉及到客户端的内容它首先简述 JSSE然后会做这样一些事情
l 在客户端使用 JSSE API
l 一步步的开发一个支持 SSL 的客户端应用程序
l 开发简单的支持 SSL 的客户端应用程序
l 从服务器端导出证书并在客户端导入
l 开发一个支持 SSL 的网页浏览器
JSSE
Java 安全套接扩展 (JSSE) 提供了 SSL 和 TLS 协议的框架及实现JSSE 将复杂的根本的加密算法抽象化了这样就降低了受到敏感或者危险的安全性攻击的风险正如你在本文中看到的那样由于它能将 SSL 无缝地结合在应用当然使安全应用的开发变得非常简单JSSE 框架可以支撑许多不同的安全通信协议如 SSL 和 以及 TLS 但是 JSE v 只实现了 SSL 和 TLS
用 JSSE 编写客户端应用程序
JSSE API 提供了扩充的网络套接字类信用和密匙管理以及为简化套接字创建而设计的套接字工厂框架以此扩充 javasecurity 和 两个包这些类都包含在 和 ssl 包中
sllSSLSocketFactory 类是一个创建安全套接字的对象工厂可以通过下面两种方法获得 SSLSocketFactory 的实例
调用 SSLSocketFactorygetDefault 来获得默认的工厂默认的工厂被配置为只允许服务器端验证 (不允许客户端验证)注意许多电子商务网站不需要客户端验证
使用指定的配置来构造一个新的工厂 (这不在本文讲述的范围内)
建立 SSLSocketFactory 实例之后你就可以通过 SSLSocketFactory 实例的 createSocket 方法创建 SSLSocket 对象了这里有一个例子该例通过 SSL 端口 (这是 HTTPS 的默认端口) 创建套接字并连接到 Sun 的 WWW 服务器
// Get a Socket factory
SocketFactory factory = SSLSocketFactorygetDefault();
// Get Socket from factory
Socket socket = factorycreateSocket( );
使用低层的 SSL 套接字
现在让我们看一个使用低层套接字在 HTTPS 服务器上打开一个 SSL 套接字连接的完整例子在这个例子中打开了一个到 HTTPS 服务器的 SSL 套接字连接并且读入默认文档的内容示例代码 展示了这个应用程序其中用于打开 SSL 套接字的代码已经加黑显示了你将会看到应用程序中其余代码就是常规的输入/输出流代码
代码示例 ReadHttpsURL
import *;
import *;
import ssl*;
public class ReadHttpsURL {
static final int HTTPS_PORT = ;
public static void main(String argv[]) throws Exception {
if (argvlength != ) {
Systemoutprintln(Usage: java ReadHttpsURL );
Systemexit();
}
// Get a Socket factory
SocketFactory factory = SSLSocketFactorygetDefault();
// Get Socket from factory
Socket socket = factorycreateSocket(argv[] HTTPS_PORT);
BufferedWriter out
= new BufferedWriter(new OutputStreamWriter(socketgetOutputStream()));
BufferedReader in
= new BufferedReader(new InputStreamReader(socketgetInputStream()));
outwrite(GET / HTTP/\n\n);
outflush();
String line;
StringBuffer sb = new StringBuffer();
while((line = inreadLine()) != null) {
sbappend(line);
}
outclose();
inclose();
Systemoutprintln(sbtoString());
}
}
用这个应用程序进行实验
拷贝 ReadHttpsURL 类的代码并粘贴到一个新文件中将该文件改名为 ReadHttpsURLjava并保存在一个你指定的目录下
使用 javac 编译 ReadHttpsURLjava
运行 ReadHttpsURL 并提供一个域名作为参数如
Prompt> java ReadHttpsURL
几秒种后你会看到许多 HTML 代码显示在屏幕上注意即使我们提供的是域名 我们打开的连接也是 这是因为我们使用的端口号 是 HTTPS 的默认端口号
再试试另一个例子如
Prompt> java ReadHttpsURL wwwjamca
这次运行会抛出如下所示的异常你能猜到是为什么吗?
Exception in thread main sslSSLHandshakeException: javasecuritycertCertificateException: Couldnt find trusted certificate at sslinternalsslBaseSSLSocketImpla(DashoA)
缘于一个很好的理由它不能运行——因为远端的服务器发送了一个客户端不认识的证书我在本文的第一部分提到过当客户端连接服务器的时候服务器发送它的证书到客户端请求验证这样第一个例子中你进入了 服务器的确发送了证书但 Java 检查了默认的证书库并认出了这个证书是由可信任的 CA 产生的默认情况下Java 信任这个 CA第二个例子中你进入的是 wwwjamca那个网端的证书不是它自己产生的就是由一个 Java 不知道的 CA 产生的因此不受信任
注意如果系统时钟没有设置正确那么它的时间就可能在证书的有效期之外服务器会认为证书无效并抛出 CertificateException 异常
为了让示例正确运行你得从 wwwjamca 导入证收到 Java 信任的证书库中