您的位置:首页 > 编程语言 > Java开发

Java下SSL的使用

2012-05-20 16:22 281 查看
实现技术:

JSSE(Java Security Socket Extension

是Sun为了解决在Internet上的实现安全信息传输的解决方案。它实现了SSL和TSL(传输层安全)协议。在JSSE中包含了数据加密,服务器验证,消息完整性和客户端验证等技术。通过使用JSSE,可以在Client和Server之间通过TCP/IP协议安全地传输数据。

为了实现消息认证。

Server需要:

1)KeyStore: 其中保存服务端的私钥

2)Trust KeyStore:其中保存客户端的授权证书

Client需要:

1)KeyStore:其中保存客户端的私钥

2)Trust KeyStore:其中保存服务端的授权证书

使用Java自带的keytool命令,去生成这样信息文件:

1)生成服务端私钥,并且导入到服务端KeyStore文件中



2)根据私钥,导出服务端证书



3)将服务端证书,导入到客户端的Trust KeyStore中



采用同样的方法,生成客户端的私钥,客户端的证书,并且导入到服务端的Trust KeyStore中

1)keytool -genkey -alias clientkey -keystore kclient.keystore

2)keytool -export -alias clientkey -keystore kclient.keystore -file client.crt

3)keytool -import -alias clientkey -file client.crt -keystore tserver.keystore



Server:




Java代码



package ssl;

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.FileInputStream;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.Socket;

import java.security.KeyStore;

import javax.net.ssl.KeyManagerFactory;

import javax.net.ssl.SSLContext;

import javax.net.ssl.SSLServerSocket;

import javax.net.ssl.TrustManagerFactory;

/**

*

* @author Leo

*/

public class Server implements Runnable{

private static final int DEFAULT_PORT = 7777;

private static final String SERVER_KEY_STORE_PASSWORD = "123456";

private static final String SERVER_TRUST_KEY_STORE_PASSWORD = "123456";

private SSLServerSocket serverSocket;

/**

* 启动程序

*

* @param args

*/

public static void main(String[] args) {

Server server = new Server();

server.init();

Thread thread = new Thread(server);

thread.start();

}

public synchronized void start() {

if (serverSocket == null) {

System.out.println("ERROR");

return;

}

while (true) {

try {

Socket s = serverSocket.accept();

InputStream input = s.getInputStream();

OutputStream output = s.getOutputStream();

BufferedInputStream bis = new BufferedInputStream(input);

BufferedOutputStream bos = new BufferedOutputStream(output);

byte[] buffer = new byte[20];

bis.read(buffer);

System.out.println("------receive:--------"+new String(buffer).toString());

bos.write("yes".getBytes());

bos.flush();

s.close();

} catch (Exception e) {

System.out.println(e);

}

}

}

public void init() {

try {

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

KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");

TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");

KeyStore ks = KeyStore.getInstance("JKS");

KeyStore tks = KeyStore.getInstance("JKS");

ks.load(new FileInputStream("src/ssl/kserver.keystore"), SERVER_KEY_STORE_PASSWORD.toCharArray());

tks.load(new FileInputStream("src/ssl/tserver.keystore"), SERVER_TRUST_KEY_STORE_PASSWORD.toCharArray());

kmf.init(ks, SERVER_KEY_STORE_PASSWORD.toCharArray());

tmf.init(tks);

ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

serverSocket = (SSLServerSocket) ctx.getServerSocketFactory().createServerSocket(DEFAULT_PORT);

serverSocket.setNeedClientAuth(true);

} catch (Exception e) {

System.out.println(e);

}

}

public void run() {

// TODO Auto-generated method stub

start();

}

}

Client:

Java代码



package ssl;

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.security.KeyStore;

import javax.net.ssl.KeyManagerFactory;

import javax.net.ssl.SSLContext;

import javax.net.ssl.SSLSocket;

import javax.net.ssl.TrustManagerFactory;

/**

* SSL Client

*

* @author Leo

*/

public class Client {

private static final String DEFAULT_HOST = "127.0.0.1";

private static final int DEFAULT_PORT = 7777;

private static final String CLIENT_KEY_STORE_PASSWORD = "123456";

private static final String CLIENT_TRUST_KEY_STORE_PASSWORD = "123456";

private SSLSocket sslSocket;

/**

* 启动客户端程序

*

* @param args

*/

public static void main(String[] args) {

Client client = new Client();

client.init();

client.process();

}

public void process() {

if (sslSocket == null) {

System.out.println("ERROR");

return;

}

try {

InputStream input = sslSocket.getInputStream();

OutputStream output = sslSocket.getOutputStream();

BufferedInputStream bis = new BufferedInputStream(input);

BufferedOutputStream bos = new BufferedOutputStream(output);

bos.write("1234567890".getBytes());

bos.flush();

byte[] buffer = new byte[20];

bis.read(buffer);

System.out.println(new String(buffer));

sslSocket.close();

} catch (IOException e) {

System.out.println(e);

}

}

public void init() {

try {

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

KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");

TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");

KeyStore ks = KeyStore.getInstance("JKS");

KeyStore tks = KeyStore.getInstance("JKS");

ks.load(new FileInputStream("src/ssl/kclient.keystore"), CLIENT_KEY_STORE_PASSWORD.toCharArray());

tks.load(new FileInputStream("src/ssl/tclient.keystore"), CLIENT_TRUST_KEY_STORE_PASSWORD.toCharArray());

kmf.init(ks, CLIENT_KEY_STORE_PASSWORD.toCharArray());

tmf.init(tks);

ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

sslSocket = (SSLSocket) ctx.getSocketFactory().createSocket(DEFAULT_HOST, DEFAULT_PORT);

} catch (Exception e) {

System.out.println(e);

}

}

}

启动Server

启动Client,发送信息。

Server接收如下:正确解密



返回Client信息,如下:



如此,就完成了服务端和客户端之间的基于身份认证的交互。

client采用kclient.keystore中的clientkey私钥进行数据加密,发送给server。

server采用tserver.keystore中的client.crt证书(包含了clientkey的公钥)对数据解密,如果解密成功,证明消息来自client,进行逻辑处理。

server采用kserver.keystore中的serverkey私钥进行数据加密,发送给client。

client采用tclient.keystore中的server.crt证书(包含了serverkey的公钥)对数据解密,如果解密成功,证明消息来自server,进行逻辑处理。

如果过程中,解密失败,那么证明消息来源错误。不进行逻辑处理。这样就完成了双向的身份认证。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐