`
sunnylocus
  • 浏览: 876668 次
  • 性别: Icon_minigender_1
  • 来自: 美国图森
社区版块
存档分类
最新评论

用JSSE实现网络安全通信

    博客分类:
  • Java
阅读更多

    在网络上信息由源主机到目标主机要经过很多路由和计算机,通常这些机器不会监听路过的信息。但在使用网络银行进行网上消费时,不加以保护的账号密码很有可能被黑客截获并利用给消费者造成不可估量的损失。

      Java安全套接字扩展(JSSE,Java Secure Socket Extension)为基于SSL和TLS协议的Java网络应用程序提供了Java API及参考实现。JSSE支持数据加密、服务器端身份验证、数据完整性。使用JSSE,能保证采用各种应用层协议(HTTP、Telnet、FTP等)的客户程序与服务器程序安全地交换数据

     要实现用JSSE交换数据,需要用到证书,获取证书有两种方式,一是从权威机构购买证书,二是创建自我签名的证书。我们用JDK现有的工具keytool创建一个自我签名的证书。

 

服务端证书

 

客户端证书

 

jks文件是一个密钥容器,证书都会存储在里面,如果要导出刚刚生成的证书,用下面的命令

keytool -export -alias keyAlias
-storepass changeit
 -file server.cer
 -keystore keystore.jks

JSSE中负责安全通信的核心类是SSLServerSocket类和SSLSocket类,它们分别是ServerSocket与Socket类的子类。SSLSocket对象由SSLSocketFactory创建,不过SSLServerSocket的accept()方法也会创建SSLSocket。SSLServerSocketFactory、SSLSocketFactory对象都由SSLContext对象创建。

 

下面是一个简单的例子,客户端和服务端采用刚才生成的两个证书进行通信,在控制台随便输入信息,服务端都会响应,输入"88"结束本次会话。

 

客户端:

package com.bill99.seashell.domain;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.security.KeyStore;

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

public class MySSLClient {
	
	private static final String SSL_TYPE = "SSL";
	private static final String X509 = "SunX509";
	private static final String KS_TYPE = "JKS";
	
	private SSLSocket sslcntSocket;
	
	public MySSLClient(String targetHost,int port) throws Exception {
		SSLContext sslContext = createSSLContext(); //创建SSL上下文
		SSLSocketFactory sslcntFactory =(SSLSocketFactory) sslContext.getSocketFactory();
		sslcntSocket = (SSLSocket) sslcntFactory.createSocket(targetHost, port);
		String[] supported = sslcntSocket.getSupportedCipherSuites();
		sslcntSocket.setEnabledCipherSuites(supported); //设置加密套件
	}
	
	private SSLContext createSSLContext() throws Exception{
		KeyManagerFactory kmf = KeyManagerFactory.getInstance(X509);
		TrustManagerFactory tmf = TrustManagerFactory.getInstance(X509);
		//-----------------------------------------------------------
		String clientKeyStoreFile = "c:\\merchant.jks"; //客户端用于证实自己身份的证书
		String cntPassphrase = "baitour";               //证书密码
		char[] cntPassword = cntPassphrase.toCharArray();
		KeyStore clientKeyStore = KeyStore.getInstance(KS_TYPE);
		clientKeyStore.load(new FileInputStream(clientKeyStoreFile),cntPassword);
		//-----------------------------------------------------------
		String serverKeyStoreFile = "c:\\paygateway.jks"; //服务端证书
		String svrPassphrase = "99bill";                 //证书密码
		char[] svrPassword = svrPassphrase.toCharArray();
		KeyStore serverKeyStore = KeyStore.getInstance(KS_TYPE);
		serverKeyStore.load(new FileInputStream(serverKeyStoreFile), svrPassword);
		
		kmf.init(clientKeyStore, cntPassword); 
		
		tmf.init(serverKeyStore);  //添加信任的证书
		
		SSLContext sslContext  = SSLContext.getInstance(SSL_TYPE);
		sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
		
		return sslContext;
	}
	
	/**
	 * 发送消息至服务器
	 * @param sayMsg 发送给服务器信息
	 * @return String 服务器响应的信息
	 * @throws IOException 发送过程Socket出错时抛出此异常
	 */
	public String sayToSvr(String sayMsg) throws IOException{
		BufferedReader ioReader = new BufferedReader(new InputStreamReader(
				sslcntSocket.getInputStream()));
		PrintWriter ioWriter = new PrintWriter(sslcntSocket.getOutputStream());

		ioWriter.println(sayMsg);
		ioWriter.flush();

		return ioReader.readLine();
	}
	
	public static void main(String[] args) throws Exception {
		MySSLClient mysslCnt = new MySSLClient("127.0.0.1",7612);
		BufferedReader ioReader = new BufferedReader(new InputStreamReader(System.in));
		String sayMsg = "";
		String svrRespMsg= "";
		while( (sayMsg = ioReader.readLine())!= null ) {
			svrRespMsg = mysslCnt.sayToSvr(sayMsg);
			if(svrRespMsg != null && !svrRespMsg.trim().equals("")) {
				System.err.println("服务器响应:"+svrRespMsg);
			}
			if(sayMsg.trim().equals("88")) {
				break ;
			}
		}
	}
}

 服务端

package com.bill99.seashell.domain;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
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 javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManagerFactory;

public class MySSLServer {

	private static final String SSL_TYPE = "SSL";
	private static final String KS_TYPE = "JKS";
	private static final String X509 = "SunX509";
	
	private final static int PORT = 7612;  //监听端口
	private final static Object lock = new Object();//对象锁
	
	private static MySSLServer mysslServer;
	
	private SSLServerSocket svrSocket;
	
	/**
	 * 通过单态模式获得MySSLServer对象
	 */
	public static MySSLServer getInstance() throws Exception {
		synchronized (lock) {
			if (mysslServer == null) {
				mysslServer = new MySSLServer();
			}
			return mysslServer;
		}
	}
	
	private MySSLServer() throws Exception{
		//输出跟踪日志
		System.setProperty("javax.net.debug","all");
		//创建SSL上下文
		SSLContext sslContext = createSSLContext();
		
		SSLServerSocketFactory serverFactory = sslContext.getServerSocketFactory();
		svrSocket =(SSLServerSocket) serverFactory.createServerSocket(PORT);
		svrSocket.setNeedClientAuth(true);  //需要验证客户的身份
		
		System.err.println("【SSL服务器启动,监听端口:"+PORT+ "】");
		System.err.println(svrSocket.getNeedClientAuth() ? "【需要验证对方身份】" : "【不需要验证对方的身份】");
		//设置支持加密的套件
		String[] supported = svrSocket.getEnabledCipherSuites();
		svrSocket.setEnabledCipherSuites(supported);
	}
	
	/**
	 * 创建上下文
	 * @return SSLContext
	 * @throws Exception 在创建SSLContext发生错误时抛出此异常
	 */
	private SSLContext createSSLContext() throws Exception{
		//证书管理器
		KeyManagerFactory kmf = KeyManagerFactory.getInstance(X509);
		//信任管理器
		TrustManagerFactory tmf = TrustManagerFactory.getInstance(X509);
		
		//服务器证书加载到证书管理器
		//----------------------------------------------------------
		String serverKeyStoreFile = "c:\\paygateway.jks"; //服务器用于证实自己身份的证书
		String svrPassphrase = "99bill";               //服务器证书密码
		char[] svrPassword = svrPassphrase.toCharArray();
		KeyStore serverKeyStore = KeyStore.getInstance(KS_TYPE);
		serverKeyStore.load(new FileInputStream(serverKeyStoreFile), svrPassword);
		kmf.init(serverKeyStore, svrPassword);
		//客户机证书加载到证书管理器
		//-----------------------------------------------------------
		String clientKeyStoreFile = "c:\\merchant.jks"; //客户端用于证实自己身份的证书
		String cntPassphrase = "baitour";               //证书密码
		char[] cntPassword = cntPassphrase.toCharArray();
		KeyStore clientKeyStore = KeyStore.getInstance(KS_TYPE);
		clientKeyStore.load(new FileInputStream(clientKeyStoreFile),cntPassword);
		tmf.init(clientKeyStore);  //添加信任的证书
		
		SSLContext sslContext  = SSLContext.getInstance(SSL_TYPE);
		sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
		
		return sslContext;
	}
	
	/**
	 * 开始服务
	 */
	public void startService() {
		SSLSocket cntSocket = null;
		BufferedReader ioReader = null;
		PrintWriter ioWriter = null;
		String tmpMsg = null;
		while( true ) {
			try {
				cntSocket =(SSLSocket) svrSocket.accept();
				System.err.println("[有客户机连接,IP:"+cntSocket.getInetAddress()+"]");
				ioReader = new BufferedReader(new InputStreamReader(cntSocket.getInputStream()));
				ioWriter = new PrintWriter(cntSocket.getOutputStream());
				
				while ( (tmpMsg = ioReader.readLine()) != null) {
					System.err.println("[客户机说:"+tmpMsg+"]");
					if("88".equals(tmpMsg)) {
						break;
					}
					tmpMsg = " **** Welcome to our website  **** ";
					ioWriter.println(tmpMsg);
					ioWriter.flush();
					System.err.println("[服务器说:"+tmpMsg+"]");
				}
			} catch(IOException e) {
				e.printStackTrace();
			} finally {
				try {
					if(cntSocket != null) cntSocket.close();
				} catch(Exception ex) {ex.printStackTrace();}
			}
		}//end while
	}//end startService method
	
	public static void main(String[] args) throws Exception {
		MySSLServer mysslSvr = MySSLServer.getInstance();
		mysslSvr.startService();

	}
}
 
3
1
分享到:
评论
2 楼 sunnylocus 2011-03-10  
xuxinyl 写道
你好,为什么我按照你的步骤去操作了,运行服务器端还是报错呢?
错误如下:
***
found key for : www.yljs88.com
chain [0] = [
[
  Version: V3
  Subject: CN=xu xin, OU=xys, O=yljs, L=Shenzhen, ST=Guangdong, C=CN
  Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5

  Key:  Sun RSA public key, 1024 bits
  modulus: 123607024255248258784439028545372026631058966832992855876875000483173298539930721531819202920732193114521618181081579266576350014370654512557051745354541444935824536358484956714753978411516947333147034447568059605065181763586882032781499880058910142827243197441307414996839234272128064359138425232459725803057
  public exponent: 65537
  Validity: [From: Tue Mar 08 18:07:47 CST 2011,
               To: Mon Jun 06 18:07:47 CST 2011]
  Issuer: CN=xu xin, OU=xys, O=yljs, L=Shenzhen, ST=Guangdong, C=CN
  SerialNumber: [    4d75fff3]

]
  Algorithm: [SHA1withRSA]
  Signature:
0000: 64 6A B8 3C 8F 49 F8 9C   10 92 BF EC BC 1F B0 53  dj.<.I.........S
0010: D1 9C E2 17 1D 8D 4D 22   C3 B0 50 A2 A7 E2 2B 65  ......M"..P...+e
0020: 6E 48 F1 89 2C B1 C9 BC   92 C8 A1 35 32 01 BC EE  nH..,......52...
0030: F1 54 BA BB E7 35 86 6C   F9 1C 82 C2 F6 C8 F5 1E  .T...5.l........
0040: 28 5D CC 98 63 78 EE BA   AA 04 B8 45 11 0A EE EA  (]..cx.....E....
0050: B8 A7 39 9B 48 D0 91 6C   C6 14 03 CE 2B 8F 61 5A  ..9.H..l....+.aZ
0060: 91 1A 32 2D C8 B1 1F 5F   81 16 6E DB 10 E9 AC 01  ..2-..._..n.....
0070: CE 97 3F 0C C9 91 DF 3D   FE 6F EE D0 B2 BA 31 B5  ..?....=.o....1.

]
***
adding as trusted cert:
  Subject: CN=li hua, OU=tianpai, O=tian, L=Shenzhen, ST=Guangdong, C=CN
  Issuer:  CN=li hua, OU=tianpai, O=tian, L=Shenzhen, ST=Guangdong, C=CN
  Algorithm: RSA; Serial number: 0x4d760069
  Valid from Tue Mar 08 18:09:45 CST 2011 until Mon Jun 06 18:09:45 CST 2011

trigger seeding of SecureRandom
done seeding SecureRandom
【SSL服务器启动,监听端口:7612】
【不需要验证对方的身份】
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
matching alias: www.yljs88.com
main, called closeSocket()

期待你的回复,谢谢。

能把你的源代码发过来我看下么,这些信息我还看不出问题所在
1 楼 xuxinyl 2011-03-09  
你好,为什么我按照你的步骤去操作了,运行服务器端还是报错呢?
错误如下:
***
found key for : www.yljs88.com
chain [0] = [
[
  Version: V3
  Subject: CN=xu xin, OU=xys, O=yljs, L=Shenzhen, ST=Guangdong, C=CN
  Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5

  Key:  Sun RSA public key, 1024 bits
  modulus: 123607024255248258784439028545372026631058966832992855876875000483173298539930721531819202920732193114521618181081579266576350014370654512557051745354541444935824536358484956714753978411516947333147034447568059605065181763586882032781499880058910142827243197441307414996839234272128064359138425232459725803057
  public exponent: 65537
  Validity: [From: Tue Mar 08 18:07:47 CST 2011,
               To: Mon Jun 06 18:07:47 CST 2011]
  Issuer: CN=xu xin, OU=xys, O=yljs, L=Shenzhen, ST=Guangdong, C=CN
  SerialNumber: [    4d75fff3]

]
  Algorithm: [SHA1withRSA]
  Signature:
0000: 64 6A B8 3C 8F 49 F8 9C   10 92 BF EC BC 1F B0 53  dj.<.I.........S
0010: D1 9C E2 17 1D 8D 4D 22   C3 B0 50 A2 A7 E2 2B 65  ......M"..P...+e
0020: 6E 48 F1 89 2C B1 C9 BC   92 C8 A1 35 32 01 BC EE  nH..,......52...
0030: F1 54 BA BB E7 35 86 6C   F9 1C 82 C2 F6 C8 F5 1E  .T...5.l........
0040: 28 5D CC 98 63 78 EE BA   AA 04 B8 45 11 0A EE EA  (]..cx.....E....
0050: B8 A7 39 9B 48 D0 91 6C   C6 14 03 CE 2B 8F 61 5A  ..9.H..l....+.aZ
0060: 91 1A 32 2D C8 B1 1F 5F   81 16 6E DB 10 E9 AC 01  ..2-..._..n.....
0070: CE 97 3F 0C C9 91 DF 3D   FE 6F EE D0 B2 BA 31 B5  ..?....=.o....1.

]
***
adding as trusted cert:
  Subject: CN=li hua, OU=tianpai, O=tian, L=Shenzhen, ST=Guangdong, C=CN
  Issuer:  CN=li hua, OU=tianpai, O=tian, L=Shenzhen, ST=Guangdong, C=CN
  Algorithm: RSA; Serial number: 0x4d760069
  Valid from Tue Mar 08 18:09:45 CST 2011 until Mon Jun 06 18:09:45 CST 2011

trigger seeding of SecureRandom
done seeding SecureRandom
【SSL服务器启动,监听端口:7612】
【不需要验证对方的身份】
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
matching alias: www.yljs88.com
main, called closeSocket()

期待你的回复,谢谢。

相关推荐

    利用java编程实现网络安全通信.zip

    本资料"利用java编程实现网络安全通信.zip"包含了一份详细的PDF文档,旨在帮助开发者理解和实践Java在网络安全通信中的应用。 在Java中,网络安全通信主要涉及以下几个关键知识点: 1. **Socket编程**:Java的...

    SSL安全网络通信源码

    在本"SSL安全网络通信源码"中,我们将探讨如何利用自签名的服务器端和客户端数字证书来实现双方的双向认证。 首先,让我们了解SSL通信的基本过程: 1. **握手阶段**:当客户端(例如浏览器)尝试连接到服务器时,...

    用jsse定制SSL

    **JSSE(Java Secure Socket Extension)是Java平台中用于实现安全网络通信的API,它提供了SSL(Secure Sockets Layer)和TLS(Transport Layer Security)协议的实现,使得开发者能够构建安全的HTTPS、SMTPS等服务...

    java网络即时通信系统

    Java的JSSE(Java Secure Socket Extension)提供了一套全面的安全框架,用于实现加密、身份验证和完整性检查。 综上所述,Java网络即时通信系统是基于Java技术构建的,利用Java的强类型、面向对象特性,结合NIO、...

    为高级 JSSE 开发人员定制 SSL

    它为Java应用程序提供了安全网络通信的能力,通过SSL/TLS协议加密和保护数据,防止在传输过程中被窃取或篡改。 JSSE的核心功能包括: 1. **KeyStores和TrustStores**:JSSE使用KeyStore存储私钥和证书,用于身份...

    java 实现数字证书的操作实现网络安全

    Java 数字证书操作是网络安全领域中的重要组成部分,主要用于身份验证和数据加密,确保网络通信的安全。在Java中,我们可以利用Java Cryptography Extension (JCE) 和 Java Secure Socket Extension (JSSE) 这些强大...

    用JSSE定制SSL连接.docx

    JSSE(Java Security Socket Extension,Java安全套接字扩展)是由Sun Microsystems为解决互联网上的安全通信问题而推出的一套解决方案。它实现了SSL(Secure Sockets Layer,安全套接层)及TLS(Transport Layer ...

    基于Java编程提高网络通信安全问题研究.zip

    "基于Java编程提高网络通信安全问题研究"的主题,旨在探讨如何通过Java编程技术来增强网络通信的安全性,防止数据泄露、中间人攻击等网络安全威胁。 首先,我们需要理解Java提供的安全框架。Java内置了强大的安全...

    直接通过Socket使用JSSE

    在Java编程环境中,Java Secure Socket Extension (JSSE) 是一个重要的安全组件,它提供了实现安全套接层(SSL)和传输层安全(TLS)协议的API。这些协议用于加密网络通信,确保数据在网络中传输时的隐私和完整性,...

    jsp-api-2.1.jar+servlet-api-2.5-6.1.9.jar+jsse.jar

    JSSE提供了加密通信和身份认证的能力,确保网络数据传输的安全性。开发者可以使用JSSE来建立安全的HTTPS连接,进行数字证书管理,以及进行加密和签名操作。这对于开发需要处理敏感信息,如网上银行、电子商务等应用...

    精通PKI网络安全认证技术与编程实现光盘源码(第四篇Java security开发)

    在网络安全领域,Public Key Infrastructure(PKI)是用于建立安全通信环境的重要技术。它通过公钥加密算法确保数据传输的安全性,为网络用户提供身份验证、数据完整性以及机密性等核心服务。本资源"精通PKI网络安全...

    即时通信系统(Java实现).

    综上所述,Java实现的即时通信系统涉及到网络编程、多线程、并发处理、数据序列化、消息推送、安全性等多个方面的知识。通过合理的设计和实现,可以构建出高效、稳定的即时通讯平台,满足类似QQ的实时聊天需求。

    jsse-samples-guides.zip

    通过这个指南,开发者将能够了解如何在Java应用程序中实现安全的网络通信,提高数据传输的安全性,防止中间人攻击、窃听和数据篡改。同时,学习如何管理和配置SSL/TLS证书,以满足不同场景的安全要求。

    第5章 网络即时通信系统.rar_java 即时通信_即时通_即时通信 java_即时通信 系统_即时通信系统

    在本主题中,我们将深入探讨基于Java实现的网络即时通信系统。即时通信(Instant Messaging,简称IM)系统是一种允许用户实时在线交流的技术,常见的如QQ、微信等。使用Java进行即时通信系统的开发,得益于其跨平台...

    Java2-Network-Security.zip_java security_network security_网络安全

    在Java2中,网络安全主要通过一系列的机制和技术来实现,包括加密通信、身份验证、授权、安全套接层(SSL)、Java安全模型以及安全管理器等。 首先,加密通信是网络安全的基础,Java提供了强大的加密库,如Java ...

    即时通信系统(Java实现)

    在这个基于Java实现的即时通信系统中,初学者可以学习到许多关于网络编程、多线程处理、数据序列化以及用户界面设计等关键知识点。 1. **Java网络编程**:Java提供了丰富的API来处理网络通信,如Socket和...

    基于Java实现即时通信系统

    7. **安全策略**:为保护用户隐私和系统安全,需要实现加密通信,如使用SSL/TLS协议。Java的JSSE(Java Secure Socket Extension)提供了一套完整的安全解决方案,支持证书管理和加密算法。 8. **消息队列**:对于...

Global site tag (gtag.js) - Google Analytics