Java SSL Socket 聊天实例

写道 通过网络给的资料,自己整理一些,很多都是转载,希望共同学习。
HTTPS简介:HTTPS就是一种安全协议,实际上应用了Netscape的安全套接字层(SSL)作为HTTP应用层的子层。
主要作用可以分为两种:
一种是建立一个信息安全通道,来保证数据传输的安全。
另一种就是确认网站的真实性。

HTTPS和HTTP的区别:
一、https协议需要到CA机构申请证书,一般免费证书很少,需要交费。
  二、http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议。
  三、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
四、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行
加密传输、身份认证的网络协议,比http协议安全。

SSL介绍:
SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持。
SSL协议可分为两层:
1、SSL记录协议(SSL Record Protocol):
它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、
加密等基本功能的支持。
2、SSL握手协议(SSL Handshake Protocol):
它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、
协商加密算法、交换加密密钥等。

SSL协议主要有哪些作用?
1)认证用户和服务器,确保数据发送到正确的客户机和服务器
   2)加密数据以防止数据中途被窃取
   3)维护数据的完整性,确保数据在传输过程中不被改变。

SSL协议的工作流程:太复杂了,这里省略。
主要有2个阶段:

写道
Java 操作ssl socket的小例子
步骤:
keytool证书与密钥管理
1)创建服务端密钥库
>keytool -genkey -keystore E:\serverkey.jks -keyalg rsa -alias ssl1 -validity 700

上述命令中:
-genkey 生成密钥对
-keystore 指定密码仓库的文件地址
-keyalg 密钥所使用的算法
-alias 密钥别名..使用密钥时是使用此别名来区分的
-validity 密钥有效期(天)..从当前系统时间开始计算
该命令成功后会要求输入密码仓库的密码..例如xiawenquan
然后是输入你的个人信息..等等。最后在E盘生成一个serverkey.jks证书

2)将服务端的公钥导出成证书
>keytool -export -alias ssl1 -file e:\ssl1.cer -keystore e:\serverkey.jks
-export 导出的意思

导出成功后就得到了ssl1.cer这一份证书了..然后就是要将这一份证书分发给客户端..客户端有了该证书后就能与服务端建立安全连接了


3)生成客户端的密钥仓库
keytool -genkey -keystore e:\clientkey.jks -keyalg rsa -alias ssl1 -validity 700
4)将ssl1.cer导入到客户端的密钥仓库里
>keytool -import -file e:\ssl1.cer -keystore e:\clientkey.jks
上述命令成功后会要求输入客户端密钥仓库的密码..,比如:xiawenquan

成功后在每次要访问服务端之前还要将该证书添加到受信域中..系统会自动从受信域中检查可用的证书来完成SSL连接通讯..

package com.xiawenquan.ssl;

/**
 * Java sslSocket 聊天实例
 *SSL Socket的服务器端
 *@Author xiawenquan
 */

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
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.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;

public class SSLServer {
	public static void startSSLServer() throws IOException {
		final int port = 16666;// 监听端口
		String keyFile = "E:\\serverkey.jks";// 密钥库文件
		String keyFilePass = "xiawenuqan";// 密钥库的密码
		String keyPass = "changeit";// 密钥别名的密码
		SSLServerSocket sslsocket = null;// 安全连接套接字
		KeyStore ks;// 密钥库
		KeyManagerFactory kmf;// 密钥管理工厂
		SSLContext sslc = null;// 安全连接方式
		// 初始化安全连接的密钥
		try {
			ks = KeyStore.getInstance("JKS");
			ks.load(new FileInputStream(keyFile), keyFilePass.toCharArray());
			// 创建管理JKS密钥库的X.509密钥管理器
			kmf = KeyManagerFactory.getInstance("SunX509");
			kmf.init(ks, keyPass.toCharArray());
			//构造SSL环境,指定SSL版本为3.0,也可以使用TLSv1,但是SSLv3更加常用
			sslc = SSLContext.getInstance("SSLv3");
			//初始化SSL环境。第二个参数是告诉JSSE使用的可信任证书的来源,
			//设置为null是从javax.net.ssl.trustStore中获得证书。第三个参数是JSSE生成的随机数,
			//这个参数将影响系统的安全性,设置为null是个好选择,可以保证JSSE的安全性。
			sslc.init(kmf.getKeyManagers(), null, null);
		} catch (KeyManagementException ex) {
			
		} catch (KeyStoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (CertificateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnrecoverableKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// 用安全连接的工厂来创建安全连接套接字
		SSLServerSocketFactory sslssf = sslc.getServerSocketFactory();
		sslsocket = (SSLServerSocket) sslssf.createServerSocket();// 创建并进入监听
		SocketAddress sa=new InetSocketAddress("localhost",port);
		sslsocket.bind(sa);
		System.out.println("Listening...");
		SSLSocket ssocket = (SSLSocket) sslsocket.accept();// 接受客户端的连接
		System.out.println("Server Connection OK~");
		System.out.println("========================");
		System.out.println("");
		// 以下代码同socket通讯实例中的代码
		BufferedReader socketIn = new BufferedReader(new InputStreamReader(
				ssocket.getInputStream()));
		BufferedReader userIn = new BufferedReader(new InputStreamReader(
				System.in));
		PrintStream socketOut = new PrintStream(ssocket.getOutputStream());
		String s;
		while (true) {
			System.out.println("Please wait client 's message..");
			System.out.println("");
			s = socketIn.readLine().trim();
			if(s != null && !s.equals("")){
				System.out.println("Client Message: " + s);
				if (s.trim().equals("BYE")){
					break;
				}
				System.out.print("Server Message: ");
				
			}
			s = userIn.readLine().trim();
			if(s != null && !s.equals("")){
				socketOut.println(s);
				if (s.trim().equalsIgnoreCase("BYE")){
					break;
				}
			}
		}
		socketIn.close();
		socketOut.close();
		userIn.close();
		sslsocket.close();
	}

	public static void main(String[] args) {
		try {
			startSSLServer();
		} catch (Exception e) {
			System.out.println("Error: " + e);
		}
	}
}
package com.xiawenquan.ssl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;

import javax.net.ssl.SSLSocketFactory;
/**
 * Java sslSocket 聊天实例
 * SSL Socket的客户端
 * @author xiawenquan
 *
 */
public class SSLClient {
	static int port = 28080;

	public static void startSSLClient() throws IOException {
		int port = 16666;// 要连接的服务器端口
		String serverAdd = "localhost";// 要连接的服务器地址192.168.1.39
		try {
			System.setProperty("javax.net.ssl.trustStore", "E:\\serverkey.jks");// 设置可信任的密钥仓库
			System.setProperty("javax.net.ssl.trustStorePassword", "xiawenuqan"); // 设置可信任的密钥仓库的密码
			SSLSocketFactory sslsf = (SSLSocketFactory) SSLSocketFactory
					.getDefault();// 利用工厂来创建SSLSocket安全套接字
			Socket csocket = sslsf.createSocket(serverAdd, port);// 创建并连接服务器
			System.out.println("Client OK~");
			System.out.println("===============");
			System.out.println("");
			// 以下代码同socket通讯实例中的代码
			BufferedReader socketIn = new BufferedReader(new InputStreamReader(
					csocket.getInputStream()));// 接受到的信息
			PrintStream socketOut = new PrintStream(csocket.getOutputStream());// 要发送的信息
			BufferedReader userIn = new BufferedReader(new InputStreamReader(
					System.in));// 用户输入信息
			String s;
			while (true) {
				System.out.print("Client Message: ");
				s = userIn.readLine().trim();
				if(s != null && !s.equals("")){
					socketOut.println(s);
					if (s.trim().equals("BYE"))
						break;
					else {
						System.out.println("Please wait Server Message..");
						System.out.println("");
					}
					
					s = socketIn.readLine();
					System.out.println("Server Message: " + s);
					if (s.trim().equalsIgnoreCase("BYE")){
						break;
					}
				}
			}
			socketIn.close();
			socketOut.close();
			userIn.close();
			csocket.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		try {
			startSSLClient();
		} catch (Exception e) {
			System.out.println("Error: " + e);
		}
	}
}

相关推荐