`

java实现SSL

 
阅读更多

SSL分为单向认证和双向认证。单向认证是客户端信任服务端,双向认证是客户端既要信任服务端而且服务端也要信任客户端。

 

不管是客户端还是服务端,都要存以下两样keystore

KeyStore:保存自己的公钥和私钥。

Trust KeyStore:保存对方的公钥证书。

 

如果是单向认证,服务器端的KeyStore存储自己的公钥和私钥,客户端的Trust KeyStore要导入服务器端的公钥证书。

如果是双向认证,在上面的基础上,客户端的KeyStore存储自己的公钥和私钥,服务器端的Trust KeyStore要导入客户端的公钥证书。

 

以上4个KeyStore可以通过以下命令生成:

keytool -genkey -alias serverkey -keystore server.keystore
keytool -export -alias serverkey -keystore server.keystore -file server.crt
keytool -import -alias serverkey -file server.crt -keystore tclient.keystore

keytool -genkey -alias clientkey -keystore client.keystore
keytool -export -alias clientkey -keystore client.keystore -file client.crt
keytool -import -alias clientkey -file client.crt -keystore tserver.keystore

 

最后看下代码实现,主要通过SSLContext对象的init方法载入KeyStore

void javax.net.ssl.SSLContext.init(KeyManager[] km, TrustManager[] tm, SecureRandom random) throws KeyManagementException

 

如果是单向认证,需要配置服务端的km和客户端的tm。如果是双向认证,需要配置服务端的km、tm和客户端的km、tm四个KeyStore。

 

完整代码

服务端

 

public class SSLServer {
	private SSLServerSocket serverSocket;
	private int PORT = 8443;
	private String workPath = SSLServer.class.getClass().getResource("/").getPath()+"com/test/coder/ssl/";
	private String serverKeyStorePath = workPath+"server.keystore";
	private String SERVER_KEY_STORE_PASSWORD = "123456";
	private String serverTrustKeyStorePath = workPath+"tserver.keystore";
	private String SERVER_TRUST_KEY_STORE_PASSWORD = "123456";

	public SSLServer() {
		try {
			KeyStore ks = KeyStore.getInstance("JKS"); // 创建JKS密钥库
			ks.load(new FileInputStream(serverKeyStorePath), SERVER_KEY_STORE_PASSWORD.toCharArray());
			// 创建管理JKS密钥库的X.509密钥管理器
			KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
			kmf.init(ks, SERVER_KEY_STORE_PASSWORD.toCharArray());
			
			KeyStore tks = KeyStore.getInstance("JKS");
			tks.load(new FileInputStream(serverTrustKeyStorePath), SERVER_TRUST_KEY_STORE_PASSWORD.toCharArray());
			TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
			tmf.init(tks);

			SSLContext sslContext = SSLContext.getInstance("SSLv3");
			sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

			// 根据上面配置的SSL上下文来产生SSLServerSocketFactory,与通常的产生方法不同
			SSLServerSocketFactory factory = sslContext.getServerSocketFactory();
			serverSocket = (SSLServerSocket) factory.createServerSocket(PORT);
		} catch (UnrecoverableKeyException e) {
			e.printStackTrace();
		} catch (KeyManagementException e) {
			e.printStackTrace();
		} catch (KeyStoreException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (CertificateException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void start(){
		while(true){
			try {
				SSLSocket socket = (SSLSocket)serverSocket.accept();
				InputStream in =socket.getInputStream();
				OutputStream out = socket.getOutputStream();
				
				byte[] b = new byte[5];
				in.read(b);
				System.out.println(new String(b));
				
				in.close();
				out.close();
				socket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public static void main(String[] args) {
		SSLServer sslServer = new SSLServer();
		sslServer.start();
	}
}

 

客户端
public class SSLClient {
	private SSLSocket socket;
	private int PORT = 8443;
	private String workPath = SSLServer.class.getClass().getResource("/").getPath()+"com/test/coder/ssl/";
	private String clientKeyStorePath = workPath+"client.keystore";
	private String CLIENT_KEY_STORE_PASSWORD = "123456";
	private String clientTrustKeyStorePath = workPath+"tclient.keystore";
	private String CLIENT_TRUST_KEY_STORE_PASSWORD = "123456";

	public SSLClient() {
		try {
			KeyStore ks = KeyStore.getInstance("JKS"); // 创建JKS密钥库
			ks.load(new FileInputStream(clientKeyStorePath), CLIENT_KEY_STORE_PASSWORD.toCharArray());
			// 创建管理JKS密钥库的X.509密钥管理器
			KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
			kmf.init(ks, CLIENT_KEY_STORE_PASSWORD.toCharArray());
			
			KeyStore tks = KeyStore.getInstance("JKS");
			tks.load(new FileInputStream(clientTrustKeyStorePath), CLIENT_TRUST_KEY_STORE_PASSWORD.toCharArray());
			TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
			tmf.init(tks);

			SSLContext sslContext = SSLContext.getInstance("SSLv3");
			sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

			// 根据上面配置的SSL上下文来产生SSLServerSocketFactory,与通常的产生方法不同
			SSLSocketFactory factory = sslContext.getSocketFactory();
			socket = (SSLSocket) factory.createSocket("127.0.0.1", PORT);
		} catch (UnrecoverableKeyException e) {
			e.printStackTrace();
		} catch (KeyManagementException e) {
			e.printStackTrace();
		} catch (KeyStoreException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (CertificateException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void start(){
		try {
			InputStream in =socket.getInputStream();
			OutputStream out = socket.getOutputStream();
			
			out.write("World".getBytes());
			
			in.close();
			out.close();
			socket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		SSLClient sslClient = new SSLClient();
		sslClient.start();
	}
}
 
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics