用J2SE 1.4进行Internet安全编程之一【转载】

 
用户密码登录 | 注册
搜索
<script language=JavaScript> function chkField(aForm) { if (!aForm.SrchStr.value) { alert("请输入需检索的词!"); aForm.SrchStr.focus(); return false; } else { if (aForm.SrchStr.value.length>30) { alert("检索的词请不要超过30个字符!"); aForm.SrchStr.focus(); return false; } } } </script>
首页 资讯中心 专题中心 信息化 招聘培训 i i 社区 社区联盟 数码摄影
产品中心 数码 手机 笔记本 DIY 台式机 服务器 网络产品 软件 导购专家
 将本页设为首页 IT两会 电子杂志 计世资讯 图书 房产 华东站 华南站 西北站 东北站 西南站
CIO俱乐部焦点 | 数据 | CIO生活 | 方案·案例展示中心 | 供求与招投标 | 论坛 | CIO俱乐部章程 
 
用J2SE 1.4进行Internet安全编程
 
 
2003-1-11 15:05:26
 
 Qusay H. Mahmoud 著 边城狂人 译 
  
 

任何在计算机网络或者 Internet 中传输的消息都可能被拦截,其中不乏一些比较敏感的内容,如信用卡号或者其它一些私人数据。为了更好的在企业环境和电子商务中使用 Internet,应用软件必须使用加密、验证和安全的通信协议来保护用户的数据安全。安全超文本传输协议 (secure Hypertext Transfer Protocol, HTTPS) 是建立于安全套接层 (Secure Sockets Layer, SSL) 上的 HTTP,它已经成功的应用于电子商务。

Java 安全套接扩展 (Java Secure Socket Extension, JSSE) 使 Internet 安全通信成为现实。它是 100% 纯 Java 实现的 SSL 框架。这个包让 Java 开发人员能够开发安全的网络应用;为基于 TCP/IP 的何应用协议,如 HTTP、FTP、Telnet、或者 NTTP,在客户端和服务器端之间建立安全的数据通道。

JSSE 已经整合在 Java 2 SDK 标准版本 1.4 (J2SE 1.4) 中了,这真是一个好消息。这意味着只要你安装了 J2SE 1.4,不需要再下载其它的包,就可以创建基于 SSL 的 Internet 应用程序了。这个系列的文章共有 2 篇,它是一本关于为今后的市场开发安全 Interent 应用的手册。这篇文章主要是讲的服务器端,而下一篇是讲客户端的。这篇文章从概览 SSL 开始,然后告诉你如何进行下列内容:

  • 使用 JSSE 的 API

  • 在你的 C/S 应用程序中结合 JSSE

  • 开发一个简单的 HTTP 服务器

  • 让 HTTP 服务器能够处理 HTTPS 请求

  • 使用包含在 J2SE 中的 keytool 产生自己的证书

  • 开发、配置和运行一个安全的 HTTP 服务器

概览 SSL

SSL 协议是 Netscape 在 1994 年开发出来的,以允许服务端 (典型的如浏览器) 和 HTTP 服务器之间能通过安全的连接来通信。它加密、来源验证、数据完整性等支持,以保护在不安全的公众网络上交换的数据。SSL 有这样一些版本:SSL 2.0 有安全隐患,现在已经几本上不用了;SSL 3.0 应用则比较广泛;最后,由 SSL 3.0 改进而来的传输层加密 (Transport Layer Security, TLS) 已经成为 Internet 标准并应用于几乎所有新近的软件中。

在数据传播之前,加密技术通过将数据转变成看起来毫无意义的内容来保护数据不被非法使用。其过程是:数据在一端 (客户端或者服务器端) 被加密,传输,再在另一端解密。

来源认证是验证数据发送者身份的一种办法。浏览器或者其它客户端第一次尝试与网页服务器进行安全连接之上的通信时,服务器会将一套信任信息以证书的形式呈现出来。

证书由权威认证机构 (CA)——值得信赖的授权者发行和验证。一个证书描述一个人的公钥。一个签名的文档会作出如下保证:我证明文档中的这个公钥属于在该文档中命名的实体。签名(权威认证机构)。目前知名的权威认证机构有 VerisignEntrustThawte 等。注意现在使用的 SSL/TLS 证书是 X.509 证书。

数据完整性就是要确保数据在传输过程中没有被改变。

SSL 和 TCP/IP 协议的层次

SSL 是名符其实的安全套接层。它的连接动作和 TCP 的连接类似,因此,你可以想象 SSL 连接就是安全的 TCP 连接,因为在协议层次图中 SSL 的位置正好在 TCP 之上而在应用层之下,如图 1 所示。注意到这点很重要。但是,SSL 不支持某些 TCP 的特性,比如频带外数据。

图 1: SSL 和 TCP/IP 协议的的层次

可交流的加密技术

SSL 的特性之一是为电子商务的事务提供可交流的加密技术和验证算法提供标准的方法。SSL 的开发者认识到不是所有人都会使用同一个客户端软件,从而不是所有客户端都会包括任何详细的加密算法。对于服务器也是同样。位于连接两端的的客户端和服务器在初始化“握手”的时候需要交流加密和解密算法(密码组)。如果它们没有足够的公用算法,连接尝试将会失败。

注意当 SSL 允许客户端和服务器端相互验证的时候,典型的作法是只有服务器端在 SSL 层上进行验证。客户端通常在应用层,通过 SSL 保护通道传送的密码来进行验证。这个模式常用于银行、股份交易和其它的安全网络应用中。

SSL 完全“握手”协议如图 2 所示。它展示了在 SSL “握手”过程中的信息交换顺序。

图 2:SSL “握手”协议

这些消息的意思如下:

1. ClientHello:发送信息到服务器的客户端,这些信息如 SSL 协议版本、会话 ID 和密码组信息,如加密算法和能支持的密匙的大小。

2. ServerHello:选择最好密码组的服务器并发送这个消息给客户端。密码组包括客户端和服务器支持。

3. Certificate:服务器将包含其公钥的证书发送给客户端。这个消息是可选的,在服务器请求验证的时候会需要它。换句话说,证书用于向客户端确认服务器的身分。

4. Certificate Request: 这个消息仅在服务器请求客户端验证它自身的时候发送。多数电子商务应用不需要客户端对自身进行。

5. Server Key Exchange:如果证书包含了服务器的公钥不足以进行密匙交换,则发送该消息。

6. ServerHelloDone:这个消息通知客户端,服务器已经完成了交流过程的初始化。

7. Certificate:仅当服务器请求客户端对自己进行验证的时候发送。

8. Client Key Exchage:客户端产生一个密匙与服务器共享。如果使用 Rivest-Shamir-Adelman (RSA) 加密算法,客户端将使用服务器的公钥将密匙加密之后再发送给服务器。服务器使用自己的私钥或者密钥对消息进行解密以得到共享的密匙。现在,客户端和服务器共享着一个已经安全分发的密匙。

9. Certificate Verify:如果服务器请求验证客户端,这个消息允许服务器完成验证过程。

10. Change Cipher Spec:客户端要求服务器使用加密模式。

11. Finished:客户端告诉服务器它已经准备好安全通信了。

12. Change Cipher Spec:服务器要求客户端使用加密模式。

13. Finished:服务器告诉客户端它已经准备好安全通信了。这是 SSL “握手”结果的标志。

14. Encrypted Data:客户端和服务器现在可以开发在安全通信通道上进行加密信息的交流了。

JSSE

Java 安全套接扩展 (JSSE) 提供一个框架及一个 100% 纯 Java 实现的 SSL 和 TLS 协议。它提供了数据加密、服务器验证、消息完成性和可选的客户端验证等机制。JSSE 的引人之外就是将复杂的、根本的加密算法抽象化了,这样就降低了受到敏感或者危险的安全性攻击的风险。另外,由于它能将 SSL 无缝地结合在应用当然,使安全应用的开发变得非常简单。JSSE 框架可以支撑许多不同的安全通信协议,如 SSL 2.0 和 3.0 以及 TLS 1.0,但是 J2SE v1.4.1 只实现了 SSL 3.0 和 TLS 1.0。

JSSE 编程

JSSE API 提供了扩充的网络套接字类、信用和密匙管理,以及为简化套接字创建而设计的套接字工厂框架,以此扩充 java.security 和 java.net 两个包。这些类都包含在 javax.net 和 javax.net.ssl 包中。

SSLSocket 和 SSLServerSocket

javax.net.ssl.SSLSocket 是 java.net.Socket 的子类,因此他支持所有标准 Socket 的方法,和一些为安全套接字新增加的方法。javax.net.ssl.SSLServerSocket 类与 SSLSocket 类相似,只是它用于创建服务器套接子,而 SSLSocket 不是。

创建一个 SSLSocket 实例有如何两种方法:

1. 用 SSLSocketFactory 实例执行 createSocket 方法来创建。

2. 通过 SSLServerSocket 的 accept 方法获得。

SSLSocketFactory 和 SSLServerSocketFactory

javax.net.ssl.SSLSocketFactory 类是用于创建安全套接字的对象工厂。javax.net.ssl.SSLServerSocketFactory 也是这样的工厂,但它用于创建安全的服务器套接字。

可以通过如下方法获得 SSLSocketFactory 实例:

1. 执行 SSLSocketFactory.getDefault 方法获得一个默认的工厂。

2. 通过特定的配置行为构造一个新的工厂。

注意默认的工厂的配置只允许服务器验证。

使现有的 Client/Server 应用变得安全

在现有的 C/S 应用中整合 SSL 以使其变得安全比较简单,使用几行 JSSE 代码就可以做到。为了使服务器变得安全,下面的例子中加黑显示的内容是必须的:

import java.io.*;

import javax.net.ssl.*;

public class Server {

int port = portNumber;

SSLServerSocket server;

try {

SSLServerSocketFactory factory =

(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();

server = (SSLServerSocket)

factory.createServerSocket(portNumber);

SSLSocket client = (SSLSocket)

server.accept();

// Create input and output streams as usual

// send secure messages to client through the

// output stream

// receive secure messages from client through

// the input stream

} catch(Exception e) {

}

}

为了使客户端变得安全,下面的例子中加黑显示的内容是必须的:

import java.io.*;

import javax.net.ssl.*;

public class Client {

...

try {

SSLSocketFactory factory = (SSLSocketFactory)

SSLSocketFactory.getDefault();

server = (SSLServerSocket)

factory.createServerSocket(portNumber);

SSLSocket client = (SSLSOcket)

factory.createSocket(serverHost, port);

// Create input and output streams as usual

// send secure messages to server through the

// output stream receive secure

// messages from server through the input stream

} catch(Exception e) {

}

}

SunJSSE 提供者

J2SE v1.4.1 和一个 JSSE 提供者,SunJSSE 一起发布。SunJSSE 安装并预登记了 Java 的加密体系。请把 SunJSSE 作为一个实现的名字来考虑,它提供了 SSL v3.0 和 TLS v1.0 的实现,也提供了普通的 SSL 和 TLS 密码组。如果你想找到你的实现 (这里是 SunJSSE) 所支持的密码组列表,可以调用 SSLSocket 的 getSupportedCipherSuites 方法。然而,不是所有这些密码组都是可用的。为了找出那些是可用的,调用 getEnabledCipherSuites 方法。这个列表可以用 setEnabledCipherSuites 方法来更改。

 上页 [ 1 2 ] 下页
 
 
(网页编辑:编程浪子
 
 
 
   
检索
 
 
  <script language=javascript> function gotoSearch() { document.location="/cio/search.asp"; } </script>
小调查
<script language=javascript> function button1_onclick() { switch(intTotalItem) { case 2: if (document.frmVote.raChoice[0].checked == true) raChoice = 1; else if (document.frmVote.raChoice[1].checked == true) raChoice = 2; else raChoice = 0; break; case 3: if (document.frmVote.raChoice[0].checked == true) raChoice = 1; else if (document.frmVote.raChoice[1].checked == true) raChoice = 2; else if (document.frmVote.raChoice[2].checked == true) raChoice = 3; else raChoice = 0; break; case 4: if (document.frmVote.raChoice[0].checked == true) raChoice = 1; else if (document.frmVote.raChoice[1].checked == true) raChoice = 2; else if (document.frmVote.raChoice[2].checked == true) raChoice = 3; else if (document.frmVote.raChoice[3].checked == true) raChoice = 4; else raChoice = 0; break; case 5: if (document.frmVote.raChoice[0].checked == true) raChoice = 1; else if (document.frmVote.raChoice[1].checked == true) raChoice = 2; else if (document.frmVote.raChoice[2].checked == true) raChoice = 3; else if (document.frmVote.raChoice[3].checked == true) raChoice = 4; else if (document.frmVote.raChoice[4].checked == true) raChoice = 5; else raChoice = 0; break; case 6: if (document.frmVote.raChoice[0].checked == true) raChoice = 1; else if (document.frmVote.raChoice[1].checked == true) raChoice = 2; else if (document.frmVote.raChoice[2].checked == true) raChoice = 3; else if (document.frmVote.raChoice[3].checked == true) raChoice = 4; else if (document.frmVote.raChoice[4].checked == true) raChoice = 5; else if (document.frmVote.raChoice[5].checked == true) raChoice = 6; else raChoice = 0; break; case 7: if (document.frmVote.raChoice[0].checked == true) raChoice = 1; else if (document.frmVote.raChoice[1].checked == true) raChoice = 2; else if (document.frmVote.raChoice[2].checked == true) raChoice = 3; else if (document.frmVote.raChoice[3].checked == true) raChoice = 4; else if (document.frmVote.raChoice[4].checked == true) raChoice = 5; else if (document.frmVote.raChoice[5].checked == true) raChoice = 6; else if (document.frmVote.raChoice[6].checked == true) raChoice = 7; else raChoice = 0; break; case 8: if (document.frmVote.raChoice[0].checked == true) raChoice = 1; else if (document.frmVote.raChoice[1].checked == true) raChoice = 2; else if (document.frmVote.raChoice[2].checked == true) raChoice = 3; else if (document.frmVote.raChoice[3].checked == true) raChoice = 4; else if (document.frmVote.raChoice[4].checked == true) raChoice = 5; else if (document.frmVote.raChoice[5].checked == true) raChoice = 6; else if (document.frmVote.raChoice[6].checked == true) raChoice = 7; else if (document.frmVote.raChoice[7].checked == true) raChoice = 8; else raChoice = 0; break; case 9: if (document.frmVote.raChoice[0].checked == true) raChoice = 1; else if (document.frmVote.raChoice[1].checked == true) raChoice = 2; else if (document.frmVote.raChoice[2].checked == true) raChoice = 3; else if (document.frmVote.raChoice[3].checked == true) raChoice = 4; else if (document.frmVote.raChoice[4].checked == true) raChoice = 5; else if (document.frmVote.raChoice[5].checked == true) raChoice = 6; else if (document.frmVote.raChoice[6].checked == true) raChoice = 7; else if (document.frmVote.raChoice[7].checked == true) raChoice = 8; else if (document.frmVote.raChoice[8].checked == true) raChoice = 9; else raChoice = 0; break; case 10: if (document.frmVote.raChoice[0].checked == true) raChoice = 1; else if (document.frmVote.raChoice[1].checked == true) raChoice = 2; else if (document.frmVote.raChoice[2].checked == true) raChoice = 3; else if (document.frmVote.raChoice[3].checked == true) raChoice = 4; else if (document.frmVote.raChoice[4].checked == true) raChoice = 5; else if (document.frmVote.raChoice[5].checked == true) raChoice = 6; else if (document.frmVote.raChoice[6].checked == true) raChoice = 7; else if (document.frmVote.raChoice[7].checked == true) raChoice = 8; else if (document.frmVote.raChoice[8].checked == true) raChoice = 9; else if (document.frmVote.raChoice[9].checked == true) raChoice = 10; else raChoice = 0; break; } document.frmVote.VoteFlg.value = "Vote"; strUrl = strUrlT + "&VoteFlg=" + document.frmVote.VoteFlg.value + "&raChoice=" + raChoice; if (intVoteNum == 1) { intVoteNum = 2; winViewResult = window.open(strUrl,"","toolbar=yes,status=0"); if (raChoice == 0) { intVoteNum = intVoteNum - 1; } } else window.alert("您已经完成投票工作,谢谢"); } function button2_onclick() { switch(intTotalItem) { case 2: if (document.frmVote.raChoice[0].checked == true) raChoice = 1; else if (document.frmVote.raChoice[1].checked == true) raChoice = 2; else raChoice = 0; break; case 3: if (document.frmVote.raChoice[0].checked == true) raChoice = 1; else if (document.frmVote.raChoice[1].checked == true) raChoice = 2; else if (document.frmVote.raChoice[2].checked == true) raChoice = 3; else raChoice = 0; break; case 4: if (document.frmVote.raChoice[0].checked == true) raChoice = 1; else if (document.frmVote.raChoice[1].checked == true) raChoice = 2; else if (document.frmVote.raChoice[2].checked == true) raChoice = 3; else if (document.frmVote.raChoice[3].checked == true) raChoice = 4; else raChoice = 0; break; case 5: if (document.frmVote.raChoice[0].checked == true) raChoice = 1; else if (document.frmVote.raChoice[1].checked == true) raChoice = 2; else if (document.frmVote.raChoice[2].checked == true) raChoice = 3; else if (document.frmVote.raChoice[3].checked == true) raChoice = 4; else if (document.frmVote.raChoice[4].checked == true) raChoice = 5; else raChoice = 0; break; case 6: if (document.frmVote.raChoice[0].checked == true) raChoice = 1; else if (document.frmVote.raChoice[1].checked == true) raChoice = 2; else if (document.frmVote.raChoice[2].checked == true) raChoice = 3; else if (document.frmVote.raChoice[3].checked == true) raChoice = 4; else if (document.frmVote.raChoice[4].checked == true) raChoice = 5; else if (document.frmVote.raChoice[5].checked == true) raChoice = 6; else raChoice = 0; break; case 7: if (document.frmVote.raChoice[0].checked == true) raChoice = 1; else if (document.frmVote.raChoice[1].checked == true) raChoice = 2; else if (document.frmVote.raChoice[2].checked == true) raChoice = 3; else if (document.frmVote.raChoice[3].checked == true) raChoice = 4; else if (document.frmVote.raChoice[4].checked == true) raChoice = 5; else if (document.frmVote.raChoice[5].checked == true) raChoice = 6; else if (document.frmVote.raChoice[6].checked == true) raChoice = 7; else raChoice = 0; break; case 8: if (document.frmVote.raChoice[0].checked == true) raChoice = 1; else if (document.frmVote.raChoice[1].checked == true) raChoice = 2; else if (document.frmVote.raChoice[2].checked == true) raChoice = 3; else if (document.frmVote.raChoice[3].checked == true) raChoice = 4; else if (document.frmVote.raChoice[4].checked == true) raChoice = 5; else if (document.frmVote.raChoice[5].checked == true) raChoice = 6; else if (document.frmVote.raChoice[6].checked == true) raChoice = 7; else if (document.frmVote.raChoice[7].checked == true) raChoice = 8; else raChoice = 0; break; case 9: if (document.frmVote.raChoice[0].checked == true) raChoice = 1; else if (document.frmVote.raChoice[1].checked == true) raChoice = 2; else if (document.frmVote.raChoice[2].checked == true) raChoice = 3; else if (document.frmVote.raChoice[3].checked == true) raChoice = 4; else if (document.frmVote.raChoice[4].checked == true) raChoice = 5; else if (document.frmVote.raChoice[5].checked == true) raChoice = 6; else if (document.frmVote.raChoice[6].checked == true) raChoice = 7; else if (document.frmVote.raChoice[7].checked == true) raChoice = 8; else if (document.frmVote.raChoice[8].checked == true) raChoice = 9; else raChoice = 0; break; case 10: if (document.frmVote.raChoice[0].checked == true) raChoice = 1; else if (document.frmVote.raChoice[1].checked == true) raChoice = 2; else if (document.frmVote.raChoice[2].checked == true) raChoice = 3; else if (document.frmVote.raChoice[3].checked == true) raChoice = 4; else if (document.frmVote.raChoice[4].checked == true) raChoice = 5; else if (document.frmVote.raChoice[5].checked == true) raChoice = 6; else if (document.frmVote.raChoice[6].checked == true) raChoice = 7; else if (document.frmVote.raChoice[7].checked == true) raChoice = 8; else if (document.frmVote.raChoice[8].checked == true) raChoice = 9; else if (document.frmVote.raChoice[9].checked == true) raChoice = 10; else raChoice = 0; break; } document.frmVote.VoteFlg.value = "View"; strUrl = strUrlT + "&VoteFlg=" + document.frmVote.VoteFlg.value + "&raChoice=" + raChoice; winViewResult = window.open(strUrl,"","toolbar=yes,status=0"); } </script>
    您对下面三个选题中的哪个最感兴趣?您希望计算机世界编辑部在信息化报道方面对哪些问题进行调查采访?
IT资产管理
联网审计
某水泥厂如何把ERP和自控系统成功嫁接在一起
沃尔玛信息化
<script language=javascript> strUrlT = '/viewResult.asp?ProjectName=您对下面三个选题中的哪个最感兴趣?您希望计算机世界编辑部在信息化报道方面对哪些问题进行调查采访?'; intTotalItem = 4; intVoteNum = 1; </script>
 
关于我们 | 客服热线 | 广告服务 | 法律声明 | 投稿指南 | 联系方式
Copyright(C) ccw.com.cn,All rights reserved
中国计算机世界出版服务公司版权所有
京 ICP 证 010182 号
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值