SSLServerSocket、SSLSocket简单例子

系统环境:

java version "1.8.0_66"  x64


一:使用keytool生成服务端证书

生成密钥对

keytool -genkeypair -alias myserver -keystore myserver.jks

输入密码123456(注意,两次输入的密码一样)

从密钥对中导出证书

keytool -exportcert -alias myserver -keystore myserver.jks -file trust.cer

把导出的证书导入到受信任的证书库中

keytool -importcert -file trust.cer -keystore trust.jks

输入密码123456(注意,两次输入的密码一样)


这样,就得到了2个jks证书文件


二:服务端代码

package com.lala.ssl;

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
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.SSLServerSocketFactory;

import org.apache.commons.io.IOUtils;

public class SSLServer
{
	public static final int port = 4488;
	
	static SSLServerSocket createServerSocket(int port)throws Exception
	{
		KeyStore ks = KeyStore.getInstance("jks");
		InputStream input = new FileInputStream("d:/tmp/myserver.jks");
		ks.load(input, "123456".toCharArray());
		
		KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
		kmf.init(ks, "123456".toCharArray());
		
		SSLContext context = SSLContext.getInstance("TLSv1.2");
		
		/**
		 * KeyManager[] 第一个参数是授权的密钥管理器,用来授权验证。TrustManager[]第二个是被授权的证书管理器,
		 * 用来验证服务器端的证书。第三个参数是一个随机数值,可以填写null。如果只是服务器传输数据给客户端来验证,就传入第一个参数就可以,
		 * 客户端构建环境就传入第二个参数。双向认证的话,就同时使用两个管理器。
		 */
		context.init(kmf.getKeyManagers(), null, null);
		
		input.close();
		
		SSLServerSocketFactory ssf = context.getServerSocketFactory();
		return (SSLServerSocket)ssf.createServerSocket(port);
	}
	public static void main(String[] args)throws Exception
	{
		final ServerSocket ss = createServerSocket(port);
		System.out.println("ssl server startup at port " + port);
		while(true)
		{
			final Socket s = ss.accept();
			new Thread(()-> {
				OutputStream output = null;
				try
				{
					output = s.getOutputStream();
					output.write("hello word".getBytes());
					output.flush();
				}catch(Exception e)
				{
					e.printStackTrace();
				}
				finally
				{
					IOUtils.closeQuietly(output);
					IOUtils.closeQuietly(s);
				}
			}).start();
		}
	}
}


三:客户端代码

package com.lala.ssl;

import java.io.FileInputStream;
import java.io.InputStream;
import java.net.Socket;
import java.security.KeyStore;

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

import org.apache.commons.io.IOUtils;

public class SSLClient
{
	static SSLSocket createSocket(String host, int port)throws Exception
	{
		KeyStore ks = KeyStore.getInstance("jks");
		InputStream input = new FileInputStream("d:/tmp/trust.jks");
		ks.load(input, "123456".toCharArray());
		
		TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
		tmf.init(ks);
		
		SSLContext context = SSLContext.getInstance("TLSv1.2");
		
		/**
		 * KeyManager[] 第一个参数是授权的密钥管理器,用来授权验证。TrustManager[]第二个是被授权的证书管理器,
		 * 用来验证服务器端的证书。第三个参数是一个随机数值,可以填写null。如果只是服务器传输数据给客户端来验证,就传入第一个参数就可以,
		 * 客户端构建环境就传入第二个参数。双向认证的话,就同时使用两个管理器。
		 */
		context.init(null, tmf.getTrustManagers(), null);
		
		input.close();
		
		SocketFactory sf = context.getSocketFactory();
		return (SSLSocket)sf.createSocket(host, port);
	}
	
	public static void main(String[] args) throws Exception
	{
		Socket s = createSocket("127.0.0.1", SSLServer.port);
		InputStream input = s.getInputStream();
		String response = IOUtils.toString(input);
		System.out.println(response);
		IOUtils.closeQuietly(input);
		IOUtils.closeQuietly(s);
	}
}


这里,服务端演示的是,服务端给连接上的客户端发送hello word消息,客户端收到之后,输出。

先启动服务端,然后启动客户端,即可看到输出

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SSL证书的添加可以通过在Socket服务端配置SSLContext来实现。在SSLContext中,可以加载服务端的证书并配置相应的参数。具体步骤如下: 1. 创建一个SSLContext实例: SSLContext sslContext = SSLContext.getInstance("TLS"); 2. 创建一个KeyManagerFactory实例,并通过其加载服务端的证书: KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); KeyStore keyStore = KeyStore.getInstance("JKS"); FileInputStream fis = new FileInputStream("path/to/keystore"); keyStore.load(fis, "password".toCharArray()); fis.close(); keyManagerFactory.init(keyStore, "password".toCharArray()); 3. 创建一个TrustManagerFactory实例,并加载信任的证书: TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); KeyStore trustStore = KeyStore.getInstance("JKS"); FileInputStream fis2 = new FileInputStream("path/to/truststore"); trustStore.load(fis2, "password".toCharArray()); fis2.close(); trustManagerFactory.init(trustStore); 4. 使用前面创建的SSLContext初始化: sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null); 5. 创建一个SSLServerSocket实例,并绑定到指定的端口: SSLServerSocketFactory sslServerSocketFactory = sslContext.getServerSocketFactory(); SSLServerSocket sslServerSocket = (SSLServerSocket) sslServerSocketFactory.createServerSocket(8000); 6. 监听并接受客户端连接: SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept(); 7. 在这个基础上,你可以使用sslSocket进行后续的数据传输。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值