Java SSL 服务器 客户端通信 试用

本文详细介绍SSL安全套接层协议的工作原理及其在Java中的实现过程,包括生成密钥、证书安装及客户端与服务器间的双向认证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简述:

SSL(百度百科)

Secure Socket Layer 安全套接层, 是为网络通信提供安全以及数据完整性的一种安全协议,在传输层对网络连接进行加密

SSL协议分为两层:

1)SSL记录协议,它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。

2)SSL握手协议,它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份验证、协商加密算法、交换加密密钥


SSL的核心是 公开密钥加密,这是种非对称密钥加密,其实直接地说就client和server各自生成一对加密密钥和解密密钥,各自吧加密密钥发给对方,这个是公开的私钥,解密方法保留在本地,加密方法传到对方那里


步骤:

1.生成server端密钥

keytool -genkey -alias serverkey -keystore key OfServer.keystore


之后会出现如下信息,


根据私钥导出服务端证书

keytool -export -alias serverkey -keystore keyOfServer.keystore -file server.crt




将服务端证书,加入客户端的认证证书列表中

keytool -import -alias serverkey -file server.crt -keystore trustOfClient.keystore


2:生成client端密钥

keytool -genkey -alias clientkey -keystore keyOfClient.keystore


根据私钥导出客户端证书

keytool -export -alias clientkey -keystore keyOfClient.keystore -file client.crt


将证书加到服务端信任列表

keytool -import -alias serverkey -file client.crt -keystore trustOfServer.keystore


至此,客户端和服务器端的证书都已经生成了


3. 之后进入代码部分

把上面四个keystore文件移入项目路径


代码:

SSLServer.java

package testSSL;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.TrustManagerFactory;

public class SSLServer extends Thread{
	private static final int SERVER_PORT = 12120; 
	private static final String SERVER_KEYSTORE_PWD = "123456"; 
	private static final String SERVER_TRUST_KEYSTORE_PWD = "654321"; 

	private SSLServerSocket serverSocket;
	
	public SSLServer() {
		// Initialize SSLServer
		try {
			//Load KeyStore And TrustKeyStore
			KeyStore keyStore = KeyStore.getInstance("JKS");
			KeyStore trustKeyStore = KeyStore.getInstance("JKS");
			try {
				keyStore.load(new FileInputStream(
						"./src/testSSL/keyOfServer.keystore"), 
						SERVER_KEYSTORE_PWD.toCharArray());
				trustKeyStore.load(new FileInputStream(
						"./src/testSSL/trustOfServer.keystore"), 
						SERVER_TRUST_KEYSTORE_PWD.toCharArray());
			} catch (CertificateException e) {
				e.printStackTrace();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			
			//Initialize KeyStore Factory
			KeyManagerFactory keyManagerFactory = 
				KeyManagerFactory.getInstance("SunX509");
			TrustManagerFactory trustManagerFactory = 
				TrustManagerFactory.getInstance("SunX509");
			try {
				keyManagerFactory.init(keyStore, SERVER_KEYSTORE_PWD.toCharArray());
			} catch (UnrecoverableKeyException e) {
				e.printStackTrace();
			}
			trustManagerFactory.init(trustKeyStore);
			
			//Initialize SSLContext
			SSLContext context = SSLContext.getInstance("SSL");
			try {
				context.init(keyManagerFactory.getKeyManagers(), 
						trustManagerFactory.getTrustManagers(), null);
			} catch (KeyManagementException e) {
				e.printStackTrace();
			}
			
			//Set up Server Socket
			try {
				serverSocket = (SSLServerSocket) context.
					getServerSocketFactory().createServerSocket(SERVER_PORT);
			} catch (IOException e) {
				e.printStackTrace();
			}
			serverSocket.setNeedClientAuth(true);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (KeyStoreException e) {
			e.printStackTrace();
		}
	}
	
	
	@Override
	public void run() {
		if(serverSocket == null){
			System.out.println("Null server socket");
			return;
		}
		while(true){
			try {
				Socket socket = serverSocket.accept();
				//Response To Client
				OutputStream output = socket.getOutputStream();
				BufferedOutputStream bufferedOutput = new BufferedOutputStream(output);
				bufferedOutput.write("Server Response: Hello".getBytes());
				bufferedOutput.flush();
				
				//Receive From Client
				InputStream input = socket.getInputStream();
				System.out.println("------Receive------");
				//use byte array to initialize the output string
				System.out.println(new String(StreamToByteArray(input))); 

			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	
	/**
	 * convert stream to Byte Array
	 * @param inputStream
	 * @return
	 * @throws IOException
	 */
	public byte[] StreamToByteArray(InputStream inputStream) throws IOException {
		ByteArrayOutputStream bout = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int readIndex = inputStream.read(buffer);
		bout.write(buffer, 0, readIndex);
		bout.flush();
		bout.close();
		inputStream.close();
		return bout.toByteArray();
	}
	
	
	public static void main(String[] args){
		System.out.println("=======Start Server !======");
		new SSLServer().start();
	}
}



SSLClient.java

package testSSL;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManagerFactory;

public class SSLClient {
	private static final String SERVER_HOST	= "127.0.0.1";
	private static final int SERVER_PORT = 12120; 
	private static final String CLIENT_KEYSTORE_PWD = "654321"; 
	private static final String CLIENT_TRUST_KEYSTORE_PWD = "654321"; 
	SSLSocket clientSocket;
	
	public SSLClient(){
		// Initialize SSLClient
		try {
			//Load KeyStore And TrustKeyStore
			KeyStore keyStore = KeyStore.getInstance("JKS");
			KeyStore trustKeyStore = KeyStore.getInstance("JKS");
			try {
				keyStore.load(new FileInputStream(
						"./src/testSSL/keyOfClient.keystore"), 
						CLIENT_KEYSTORE_PWD.toCharArray());
				trustKeyStore.load(new FileInputStream(
						"./src/testSSL/trustOfClient.keystore"), 
						CLIENT_TRUST_KEYSTORE_PWD.toCharArray());
			} catch (CertificateException e) {
				e.printStackTrace();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			
			//Initialize KeyStore Factory
			KeyManagerFactory keyManagerFactory = 
				KeyManagerFactory.getInstance("SunX509");
			TrustManagerFactory trustManagerFactory = 
				TrustManagerFactory.getInstance("SunX509");
			try {
				keyManagerFactory.init(keyStore, CLIENT_KEYSTORE_PWD.toCharArray());
			} catch (UnrecoverableKeyException e) {
				e.printStackTrace();
			}
			trustManagerFactory.init(trustKeyStore);
			
			//Initialize SSLContext
			SSLContext context = SSLContext.getInstance("SSL");
			try {
				context.init(keyManagerFactory.getKeyManagers(), 
						trustManagerFactory.getTrustManagers(), null);
			} catch (KeyManagementException e) {
				e.printStackTrace();
			}
			
			//Set up Client Socket
			try {
				clientSocket = (SSLSocket) context.
					getSocketFactory().createSocket(SERVER_HOST, SERVER_PORT);
			} catch (IOException e) {
				e.printStackTrace();
			}
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (KeyStoreException e) {
			e.printStackTrace();
		}
	}
	

	private void Test() {
		if(clientSocket == null){
			System.out.println("NULL clientSocket");
			return;
		}
		
		// Run Client Test
		InputStream input = null;
		OutputStream output = null;
		try {
			input = clientSocket.getInputStream();
			output = clientSocket.getOutputStream();
		} catch (IOException e) {
			e.printStackTrace();
		} 
		
		//Output Message To Server
		BufferedOutputStream bufferedOutput = new BufferedOutputStream(output);
		try {
			//output to Server
			bufferedOutput.write("Client Test Running".getBytes());
			bufferedOutput.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		//Output To Client Console
		try {
			System.out.println(new String(StreamToByteArray(input)));
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e1) {
			e1.printStackTrace();
		}
		
//		//close client socket
//		try {
//			clientSocket.close();
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
	}
	
	
	/**
	 * convert stream to Byte Array
	 * @param inputStream
	 * @return
	 * @throws IOException
	 */
	public byte[] StreamToByteArray(InputStream inputStream) throws IOException {
		ByteArrayOutputStream bout = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int readIndex = inputStream.read(buffer);
		bout.write(buffer, 0, readIndex);
		bout.flush();
		bout.close();
		inputStream.close();
		return bout.toByteArray();
	}
	
	
	public static void main(String[] args) {
		new SSLClient().Test();
	}
}

输出:

server端

client端



项目下载地址:

http://download.youkuaiyun.com/detail/anialy/5051274


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值