jsse.jar:JSSE应用实例



数据在网络传输是无所不在但是如果数据中包含了些私有信息如:密码或信用卡号码那么就要使数据对于那些未被授权用户保密同样也要确信数据在传输过程中有没有被故意或无意更改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 协议安全增加用于网络通信所以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


SSL 是Netscape公司于1994年开发后来应用到因特网成了个标准
SSL提供个高标准在客户和服务器发送加密消息的前SSL握手描述如下图:

\" border=0>


SSL消息按如下顺序发送:
1.Client Hello: 客户发送服务器信息包括它所支持密码组密码组中有密码算法和钥匙大小;
2.Server Hello:服务器选择客户和服务器都支持密码组到客户
3.Certicate: 服务器发送个证书或个证书链到客户端个证书链开始于服务器公共钥匙证书并结束于证明权威根证书这个消息是可选但服务器证书需要时必须使用它
4.Certicate request:当服务器需要鉴别客户时它发送个证书请求到客户端在网络这个消息很少发送
5.Server key exchange:服务器当发送来公共钥匙对钥匙交换不是很充分时发送个服务器钥匙交换消息
6.Server hello done:服务器告诉客户完成它化流通消息
7.Certicate:假如服务器需要个客户证书时客户端发送个证书链(只有在服务器需要客户证书时)
8.Client key exchange:客户产生用于对称算法个钥匙对RSA客户用服务器公共钥匙加密这个钥匙信息并把它送到服务器
9.Certicate very:在网络这个消息很少发送它主要是用来允许服务器结束对客户鉴别处理当用这个消息时客户发送用密码数字签名信息到服务端当服务端用公共钥匙解密这个消息时服务器能够鉴别客户
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.X509Certicate;

//for a simple server
public ClassFileServer extends ClassServer {

private String docroot;

private DefaultServerPort = 2001;

public ClassFileServer(ServerSocket ss, String docroot) throws IOException
{
super(ss);
this.docroot = docroot;
}

public getBytes(String path)
throws IOException
{
.out.prln(\"reading: \" + path);
File f = File(docroot + File.separator + path);
length = ()(f.length);
(length 0) {
throw IOException(\"File length is zero: \" + path);
} {
FileInputStream fin = FileInputStream(f);
DataInputStream in = DataInputStream(fin);

codes = [length];
in.readFully(codes);
codes;
}
}

public void (String args)
{
.out.prln(
\"USAGE: java ClassFileServer port docroot [TLS [true]]\");
.out.prln(\"\");
.out.prln(
\"If the third argument is TLS, it will start as\" +
\"a TLS/SSL file server, otherwise, it will be\" +
\"an ordinary file server. \" +
\"If the fourth argument is true,it will require\" +
\"client authentication as well.\");

port = DefaultServerPort;
String docroot = \"\";

(args.length >= 1) {
port = Integer.parseInt(args[0]);
}

(args.length >= 2) {
docroot = args[1];
}
String type = \"PlainSocket\";
(args.length >= 3) {
type = args[2];
}
try {
ServerSocketFactory ssf =
ClassFileServer.getServerSocketFactory(type);
ServerSocket ss = ssf.createServerSocket(port);


(args.length >= 4 && args[3].equals(\"true\")) {
((SSLServerSocket)ss).NeedClientAuth(true);
}
ClassFileServer(ss, docroot);
} catch (IOException e) {
.out.prln(\"Unable to start ClassServer: \" +
e.getMessage);
e.prStackTrace;
}
}

private ServerSocketFactory getServerSocketFactory(String type) {
(type.equals(\"TLS\")) {
SSLServerSocketFactory ssf = null;
try {
// 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( FileInputStream(\"testkeys\"), passphrase);//存储钥匙文件.
kmf.init(ks, passphrase);
ctx.init(kmf.getKeyManagers, null, null);

ssf = ctx.getServerSocketFactory;
ssf;
} catch (Exception e) {
e.prStackTrace;
}
} {
ServerSocketFactory.getDefault;
}
null;
}
}

以及:
import java.io.*;
import java.net.*;
import javax.net.*;

public abstract ClassServer implements Runnable {

private ServerSocket server = null;
protected ClassServer(ServerSocket ss)
{
server = ss;
Listener;
}

public abstract getBytes(String path)
throws IOException, FileNotFoundException;

public void run
{
Socket ;

// accept a connection
try {
= server.accept;
} catch (IOException e) {
.out.prln(\"Class Server died: \" + e.getMessage);
e.prStackTrace;
;
}

// create a thread to accept the next connection
Listener;

try {
DataOutputStream out =
DataOutputStream(.getOutputStream);
try {
// get path to file from header
BufferedReader in =
BufferedReader(
InputStreamReader(.getInputStream));
String path = getPath(in);
// retrieve codes
codes = getBytes(path);
// send codes in response (assumes HTTP/1.0 or later)
try {
out.writeBytes(\"HTTP/1.0 200 OK\");
out.writeBytes(\"Content-Length: \" + codes.length +
\"\");
out.writeBytes(\"Content-Type: text/html\");
out.write(codes);
out.flush;
} catch (IOException ie) {
ie.prStackTrace;
;
}

} catch (Exception e) {
e.prStackTrace;
// write out error response
out.writeBytes(\"HTTP/1.0 400 \" + e.getMessage + \"\");
out.writeBytes(\"Content-Type: text/html\");
out.flush;
}

} catch (IOException ex) {
// eat exception (could log error to log file, but
// write out to stdout for now).
.out.prln(\"error writing response: \" + ex.getMessage);
ex.prStackTrace;

} finally {
try {
.close;
}catch (IOException e) {
}
}
}

private void Listener
{
( Thread(this)).start;
}

private String getPath(BufferedReader in)
throws IOException
{
String line = in.readLine;
.out.prln(\"line =\"+line);
String path = \"\";
// extract from GET line
(line.startsWith(\"GET /\")) {
line = line.sub(5, line.length-1).trim;
index = line.indexOf(\' \');
(index != -1) {
path = line.sub(0, index);
}
}

// eat the rest of header
do {
line = in.readLine;
} while ((line.length != 0) &&
(line.charAt(0) != \'\') && (line.charAt(0) != \'\'));

(path.length != 0) {
path;
} {
throw IOException(\"Malformed Header\");
}
}
}

这个服务器默认端口号是:2001你可以将服务器根目录设在任何目录如启动服务器用: java ClassFileServer 2001(端口号) D:j2sdk14j2sdk-1_4_0-docdocsguidesecurityjssesamples(根目录) tls(安全通信)

为了证明client ?server安全通信可以写个client 如下:
import java.net.*;
import java.io.*;
import javax.net.ssl.*;

public SSLSocketClient {

public void (String args) throws Exception {
try {
SSLSocketFactory factory =
(SSLSocketFactory)SSLSocketFactory.getDefault;
SSLSocket =
(SSLSocket)factory.createSocket(\"localhost\", 2001);

.startHandshake;
PrWriter out = PrWriter(
BufferedWriter(
OutputStreamWriter(
.getOutputStream)));



out.prln(\"GET http://localhost:2001/index.html HTTP/1.1\");
out.prln;
out.flush;

/*
* Make sure there were no surprises
*/
(out.checkError)
.out.prln(
\"SSLSocketClient: java.io.PrWriter error\");

/* read response */
BufferedReader in = BufferedReader(
InputStreamReader(
.getInputStream));

String inputLine;
while ((inputLine = in.readLine) != null)
.out.prln(inputLine);

in.close;
out.close;
.close;

} catch (Exception e) {
e.prStackTrace;
}
}
}
我们可以运行: java SSLSocketClient 由于加密跟解密是非常耗时也许比较慢
在这个测试我们用算法是: SunX509钥匙是JKS(可以用 keytool工具添加及修改)储存钥匙文件是:testkeys(可以从jdk14 文档资料中找到)运行这个文件还必须要有个证书文件samplecacerts(也可以在jdk14 文档资料中找到)并替换
>java-home</lib/security/cacerts或者加上个参数: Djavax.net.ssl.trustStore=path_to_samplecacerts_file.
Java安全性是非常完善微软net安全性都或多或少借鉴了java功能而JSSE在网络上安全传输秘密信息是非常有用
Tags:  单片机应用实例 数据库应用实例 信息技术应用实例 jsse.jar

延伸阅读

最新评论

发表评论