一 使用java生成相关证书文件
1. 进入java安装目录的bin文件夹中 cd /java/bin
2. 创建一个客户端keystore文件,秘钥: clientkeys
keytool -genkey -alias clientkeys -keystore clientkeys
3. 将客户端keystore文件导出成证书格式,秘钥: clientkeys
keytool -export -alias clientkeys -keystore clientkeys -file clientkeys.cer
4. 创建一个服务器端keystore文件,秘钥: serverkeys
keytool -genkey -alias serverkeys -keystore serverkeys
5. 将服务器端keystore文件导出成证书格式,秘钥: serverkeys
keytool -export -alias serverkeys -keystore serverkeys -file serverkeys.cer
6. 将客户端证书导入到服务器端受信任的keystore中,秘钥: servertrust
keytool -import -alias clientkeys -keystore servertrust -file clientkeys.cer
7. 将服务器端证书导入到客户端受信任的 keystore 中,秘钥: clienttrust
keytool -import -alias serverkeys -keystore clienttrust -file serverkeys.cer
二 将上述生成的文件导入项目的src目录下
三 实现ssl的方式
第一种:服务端代码如下:
package demo1;
import java.io.*;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
public class SSLServer {
private SSLServerSocket serverSocket = null;
public SSLServer() throws Exception {
System.setProperty("javax.net.ssl.keyStore","src/serverkeys" );
System.setProperty("javax.net.ssl.keyStorePassword","serverkeys" );
System.setProperty("javax.net.ssl.trustStore","src/servertrust");
System.setProperty("javax.net.ssl.trustStorePassword","servertrust");
// 通过套接字工厂,获取一个服务器端套接字
SSLServerSocketFactory socketFactory = (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
serverSocket = (SSLServerSocket)socketFactory.createServerSocket(8080);
}
private void runServer() {
while (true) {
try {
System.out.println("服务端启动成功,等待连接。。。");
// 服务器端套接字进入阻塞状态,等待来自客户端的连接请求
SSLSocket socket = (SSLSocket) serverSocket.accept();
// 获取服务器端套接字输入流
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 从输入流中读取客户端用户名和密码
String str = input.readLine();
System.out.println("服务器接收到的信息:"+str);
// 获取服务器端套接字输出流
PrintWriter output = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
// ssl连接成功
output.println("ssl验证成功");
// 关闭流资源和套接字资源
output.close();
input.close();
socket.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
public static void main(String args[]) throws Exception {
SSLServer server = new SSLServer();
server.runServer();
}
}
客户端代码如下:
package demo1;
import java.io.*;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
public class SSLClient {
private SSLSocket socket = null;
public SSLClient() throws IOException {
System.setProperty("javax.net.ssl.keyStore","src/clientkeys" );
System.setProperty("javax.net.ssl.keyStorePassword","clientkeys" );
System.setProperty("javax.net.ssl.trustStore","src/clienttrust");
System.setProperty("javax.net.ssl.trustStorePassword","clienttrust");
// 通过套接字工厂,获取一个客户端套接字
SSLSocketFactory socketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
socket = (SSLSocket) socketFactory.createSocket("localhost", 8080);
}
public void connect() {
try {
// 获取客户端套接字输出流
PrintWriter output = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
// 通过输出流发送到服务器端
output.println("hello,server");
output.flush();
// 获取客户端套接字输入流
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 从输入流中读取服务器端传送的数据内容,并打印出来
String response = input.readLine();
System.out.println(response);
// 关闭流资源和套接字资源
output.close();
input.close();
socket.close();
} catch (IOException ioException) {
ioException.printStackTrace();
} finally {
System.exit(0);
}
}
public static void main(String args[]) throws IOException {
new SSLClient().connect();
}
}
第二种方式:服务端代码如下:
package demo2;
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;
public class SSLServer {
private SSLServerSocket serverSocket;
/**
* 启动程序
*
* @param args
*/
public static void main(String[] args) {
SSLServer server = new SSLServer();
server.init();
server.start();
}
/**
* SSL Server Socket
*/
public void start() {
if (serverSocket == null) {
System.out.println("socket初始化错误");
return;
}
System.out.println("服务端已启动");
while (true) {
try {
Socket s = serverSocket.accept();
System.out.println("连接成功...");
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(new String(buffer));
bos.write("hello client".getBytes());
bos.flush();
s.close();
} catch (Exception e) {
System.out.println(e);
}
}
}
/**
*
* 初始化SSLServerSocket
* 导入服务端私钥KeyStore,导入服务端受信任的KeyStore(客户端的证书)
*
*/
public void init() {
try {
SSLContext ctx = SSLContext.getInstance("SSL");
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("src/serverkeys"), "serverkeys".toCharArray());
KeyStore tks = KeyStore.getInstance("JKS");
tks.load(new FileInputStream("src/servertrust"), "servertrust".toCharArray());
kmf.init(ks, "serverkeys".toCharArray());
tmf.init(tks);
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
serverSocket = (SSLServerSocket) ctx.getServerSocketFactory().createServerSocket(8888);
serverSocket.setNeedClientAuth(true);
} catch (Exception e) {
e.printStackTrace();
}
}
}
客户端如下:
package demo2;
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
*
*/
public class SSLClient{
private SSLSocket sslSocket;
/**
* 启动客户端程序
* @param args
*/
public static void main(String[] args) {
SSLClient client = new SSLClient();
client.init();
client.process();
}
/**
* 通过ssl socket与服务端进行连接,并且发送一个消息
*/
public void process() {
if (sslSocket == null) {
System.out.println("socket初始化错误");
return;
}
try {
InputStream input = sslSocket.getInputStream();
OutputStream output = sslSocket.getOutputStream();
BufferedInputStream bis = new BufferedInputStream(input);
BufferedOutputStream bos = new BufferedOutputStream(output);
bos.write("hello server".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);
}
}
/**
* 初始化SSLSocket
* 导入客户端私钥KeyStore,导入客户端受信任的KeyStore(服务端的证书)
*/
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/clientkeys"), "clientkeys".toCharArray());
tks.load(new FileInputStream("src/clienttrust "), "clienttrust".toCharArray());
kmf.init(ks, "clientkeys".toCharArray());
tmf.init(tks);
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
sslSocket = (SSLSocket) ctx.getSocketFactory().createSocket("127.0.0.1", 8888);
} catch (Exception e) {
System.out.println(e);
}
}
}
注:SSLContext.getInstance("SSL"),其中SSL为数据协议类型,也可以使用TLSv1(报错的话可能是版本太低,使用TLSv1.2试试)