SVN8.COM - SVN中文技术网

投递文章 投稿指南 SVN中文技术网公告:技术交流诚聘优秀版主最新公告
搜索: 您的位置主页>JAVA技术>J2SE>JSSE的应用

JSSE的应用

SVN技术网 www.svn8.com 2008-10-08 23:26:15   来源:   作者:  评论:0 点击:
数据在网络的传输是无所不在的,但是如果数据中包含了一些私有的信息,如:密码或信用卡号码,那么就要使数据对于那些未被授权的用户保密。同样,也要确信数据在传输过程中有没有被故意或无意更改。Secure Sockets Layer(SSL) 和Transport Layer Security(TLS)协议被用来保护数据在网络传输过程中的秘密性和完整性。
Java Secure Socket Extension(JSSE)能够保证网络的通信安全。它提供了一套框架和java版本的SSL和TLS协议的实现,也包括了广泛的功能,如:数据加密,服务器证明,消息完整性,以及可选的客户证明。使用JSSE,开发者能够提供一个基于任何协议之上(如: Hypertext Transfer Protocol(Http) , Telnet, or FTP, over TCP/IP)的客户和服务器的安全数据通道。
JSSE是基于安全算法和握手机制之上的合成体。JSSE将危险的安全弱点降到最低点,并且它减轻了开发者的负担,使得开发者可以很轻松的整合到程序中。
SSL(Secure Sockets Layer)是JSSE中的重要的部分。SSL是用的最广泛的实现网络的加密协议。SSL用一个密码处理来提供网络安全通信。SSL是基于标准的TCP/IP socket协议的安全增加用于网络通信,所以SSL是位于传输层和应用程序层之间。最普通的使用SSL的是HTTP(Hypertext Transfer Protocol),用于网络页面。其他的如: Net News Transfer Protocol (NNTP), Telnet, Lightweight Directory Access Protocol (LDAP), Interactive Message Access Protocol (IMAP), and File Transfer Protocol (FTP),也能够使用SSL。
TCP/IP Protocol Stack With SSL 
TCP/IP Layer
 Protocol
 
应用程序层
     HTTP, NNTP, Telnet, FTP, etc.
 
Secure Sockets Layer
     SSL
 
传输层
     TCP
 
网络层
     IP
 
 
SSL 是Netscape公司于1994年开发的。后来应用到因特网成了一个标准。
SSL提供一个高标准的在客户和服务器发送加密消息之前的SSL握手描述,如下图:

 
SSL消息按如下顺序发送:
1.Client Hello: 客户发送服务器信息,包括它所支持的密码组。密码组中有密码算法和钥匙大小;
2.Server Hello:服务器选择客户和服务器都支持的密码组到客户。
3.Certificate: 服务器发送一个证书或一个证书链到客户端,一个证书链开始于服务器公共钥匙证书并结束于证明权威的根证书。这个消息是可选的,但服务器证书需要时,必须使用它。
4.Certificate request:当服务器需要鉴别客户时,它发送一个证书请求到客户端。在网络程序中,这个消息很少发送。
5.Server key exchange:服务器当发送来的公共钥匙对钥匙交换不是很充分时,发送一个服务器钥匙交换消息。
6.Server hello done:服务器告诉客户完成它的初始化流通消息。
7.Certificate:假如服务器需要一个客户证书时,客户端发送一个证书链。(只有在服务器需要客户证书时)
8.Client key exchange:客户产生用于对称算法的一个钥匙。对RSA客户用服务器公共钥匙加密这个钥匙信息并把它送到服务器。
9.Certificate verify:在网络程序中,这个消息很少发送,它主要是用来允许服务器结束对客户的鉴别处理。当用这个消息时,客户发送用密码函数的数字签名的信息到服务端,当服务端用公共钥匙解密这个消息时,服务器能够鉴别客户。
10.Change cipher spec:客户发送一个消息告诉服务器改变加密模式。
11.Finished:客户告诉服务器它已准备安全数据通信。
12.Change cipher spec:服务器发送一个消息到客户端并告诉客户修改加密模式。
13.Finished:服务器告诉客户端它已准备好安全数据通信。这是client-server握手协议最后一步。
14.Encrypted data:客户同服务器用对称加密算法和密码函数,并用客户发送到服务器的秘密钥匙加密通信。
下面有一个例子可以简单的实现JSSE:
服务器端程序:
import java.io.*;
import java.net.*;
import java.security.KeyStore;
import javax.net.*;
import javax.net.ssl.*;
import javax.security.cert.X509Certificate;
 
//for a simple server
public class ClassFileServer extends ClassServer {
 
private String docroot;
 
private static int DefaultServerPort = 2001;
 
public ClassFileServer(ServerSocket ss, String docroot) throws IOException
{
super(ss);
this.docroot = docroot;
}
 
public byte[] getBytes(String path)
throws IOException
{
System.out.println("reading: " + path);
File f = new File(docroot + File.separator + path);
int length = (int)(f.length());
if (length == 0) {
throw new IOException("File length is zero: " + path);
} else {
FileInputStream fin = new FileInputStream(f);
DataInputStream in = new DataInputStream(fin);
 
byte[] bytecodes = new byte[length];
in.readFully(bytecodes);
return bytecodes;
}
}
 
public static void main(String args[])
{
System.out.println(
"USAGE: java ClassFileServer port docroot [TLS [true]]");
System.out.println("");
System.out.println(
"If the third argument is TLS, it will start asn" +
"a TLS/SSL file server, otherwise, it will ben" +
"an ordinary file server. n" +
"If the fourth argument is true,it will requiren" +
"client authentication as well.");
 
int port = DefaultServerPort;
String docroot = "";
 
if (args.length >= 1) {
port = Integer.parseInt(args[0]);
}
 
if (args.length >= 2) {
docroot = args;
}
String type = "PlainSocket";
if (args.length >= 3) {
type = args;
}
try {
ServerSocketFactory ssf =
ClassFileServer.getServerSocketFactory(type);
ServerSocket ss = ssf.createServerSocket(port);
if (args.length >= 4 && args.equals("true")) {
((SSLServerSocket)ss).setNeedClientAuth(true);
}
new ClassFileServer(ss, docroot);
} catch (IOException e) {
System.out.println("Unable to start ClassServer: " +
e.getMessage());
e.printStackTrace();
}
}
 
private static ServerSocketFactory getServerSocketFactory(String type) {
if (type.equals("TLS")) {
SSLServerSocketFactory ssf = null;
try {
// set up key manager to do server authentication
SSLContext ctx;
KeyManagerFactory kmf;
KeyStore ks;
char[] passphrase = "passphrase".toCharArray();
 
ctx = SSLContext.getInstance("TLS");
kmf = KeyManagerFactory.getInstance("SunX509");//加密算法.
ks = KeyStore.getInstance("JKS");//钥匙存储名字.可以用keytool工具产生.
 
ks.load(new FileInputStream("testkeys"), passphrase);//存储钥匙文件.
kmf.init(ks, passphrase);
ctx.init(kmf.getKeyManagers(), null, null);
 
ssf = ctx.getServerSocketFactory();
return ssf;
} catch (Exception e) {
e.printStackTrace();
}
} else {
return ServerSocketFactory.getDefault();
}
return null;
}
}
 
以及:
import java.io.*;
import java.net.*;
import javax.net.*;
 
public abstract class ClassServer implements Runnable {
 
private ServerSocket server = null;
protected ClassServer(ServerSocket ss)
{
server = ss;
newListener();



技术交流 录入:SVN中文技术网[www.svn8.com]
Tags:  
责任编辑:
  • 请文明参与讨论,禁止漫骂攻击。 用户名:新注册) 密码: 匿名:
    评论总数:0 [ 查看全部 ] 网友评论
    关于我们 - 联系我们 - 广告服务 - RSS订阅 - 网站地图 - 返回顶部