`
sundoctor
  • 浏览: 325400 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

在mina中实现TSL/SSL双向认证连接(1)

    博客分类:
  • mina
阅读更多
本文需要读者对mina和SSl原理有一定的了解,所以本文中对mina和SSL的原理,不做详细的介绍。

TSL/SSL双向认证连接:Server端和Client端通信,需要进行授权和身份的验证,即Client只能接受Server的消息,Server只能接受Client的消息。这样就可以在客户机和服务器之间通过TCP/IP协议安全地传输数据。

在mina中实现TSL/SSL双向认证连接,本人目前所知有三种方式:
1.Server端和Client端各自拥有自签名的私有密钥证书,重写的 javax.net.ssl.X509TrustManager接口中的三个方法实现Server端和Client端信认证书。
2.Server端和Client端各自拥有自签名的私有密钥证书,并且互相交换公钥,通过对方公钥互相信认对方证书。
3.Server端和Client端各自拥有可信认的第三方认证机构(CA)签名私有密钥证书,通过CA互相信认对方证书。
以上三种方式,实现复杂度从低到高,灵活度安全性也从低到高。本系列文章将将会从简到难分别介绍三种方式的TSL/SSL双向认证连接。

下面我们介绍第一种实现方式:Server端和Client端各自拥有自签名的私有密钥证书,重写的 javax.net.ssl.X509TrustManager接口中的三个方法实现Server端和Client端信认证书。

首先,创建Server端和Client端各自的私有密钥证书,在这里使用keytool,关于keytool的使用在这里不作详细介绍,请参考它处。

1.创建Server端KeyStore文件serverKeys.jks,包含一个用于服务器的证书 :
引用
keytool -genkey -alias server -keysize 1024 -validity 3650 -keyalg RSA -dname "CN=sundoctor.com, OU=Developer,O=Techstar, L=Beijing, S=Beijing, C=CH" -keypass 123456 -storepass 123456 -keystore serverKeys.jks


2.创建Client端KeyStore文件clientKeys.jks,分别包含用于虚构的通信者 Alice 和 Bob 的证书 :
引用
keytool -genkey -alias alice -keysize 1024 -validity 3650 -keyalg RSA -dname "CN=Aclie, OU=Developer,O=Techstar, L=Beijing, S=Beijing, C=CH" -keypass 123456 -storepass 123456 -keystore clientKeys.jks

keytool -genkey -alias bob -keysize 1024 -validity 3650 -keyalg RSA -dname "CN=Bob, OU=Developer,O=Techstar, L=Beijing, S=Beijing, C=CH" -keypass 123456 -storepass 123456 -keystore clientKeys.jks


其次重写的 javax.net.ssl.X509TrustManager接口中的三个方法实现Server端和Client端信认证书,代码中BogusTrustManagerFactory类有关X509TrustManager实现的片断,具体参考源码
	static final X509TrustManager X509 = new X509TrustManager() {

		/**
		 * 确认和信任将其用于基于身份验证类型的客户端 SSL 身份验证
		 */
		public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

			if (x509Certificates == null || x509Certificates.length == 0)
				throw new IllegalArgumentException("null or zero-length certificate chain");
			if (s == null || s.length() == 0)
				throw new IllegalArgumentException("null or zero-length authentication type");

			boolean br = false;
			Principal principal = null;
			for (X509Certificate x509Certificate : x509Certificates) {
				principal = x509Certificate.getSubjectDN();
				if (principal != null && (StringUtils.contains(principal.getName(), "Alice") || StringUtils.contains(principal.getName(), "Bob"))) {
					br = true;
					return;
				}
			}

			if (!br) {
				throw new CertificateException("连接认证失败!");
			}
		}

		/**
		 * 确认和信任将其用于基于身份验证类型的服务器 SSL 身份验证
		 */
		public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
			if (x509Certificates == null || x509Certificates.length == 0)
				throw new IllegalArgumentException("null or zero-length certificate chain");
			if (s == null || s.length() == 0)
				throw new IllegalArgumentException("null or zero-length authentication type");

			boolean br = false;
			Principal principal = null;
			for (X509Certificate x509Certificate : x509Certificates) {
				principal = x509Certificate.getSubjectDN();
				if (principal != null && (StringUtils.contains(principal.getName(), "sundoctor.com"))) {
					br = true;
					return;
				}
			}

			if (!br) {
				throw new CertificateException("连接认证失败!");
			}
		}

		public X509Certificate[] getAcceptedIssuers() {
			return new X509Certificate[0];
		}
	};

在这里checkClientTrusted(X509Certificate[] x509Certificates, String s)验证客户端证书,在这里只是简单的验证一下客户端证书CN是否为Alice或Bob, checkServerTrusted(X509Certificate[] x509Certificates, String s)验证服务端证书,这里只是简单的验证一下服务端的CN是否为sundoctor.com。更复杂的验证,大家可以自行实现。

最后是创建服务端和客户端SSLContext工厂类,分别初始化服务端和客户端的SSLContext
// Initialize the SSLContext to work with our key managers.
SSLContext sslContext = SSLContext.getInstance(PROTOCOL);
sslContext.init(getKeyManagers(serverKeys, serverKeysPassword), BogusTrustManagerFactory.X509_MANAGERS, null);

初始化SSLContext需要KeyManagers和TrustManager,TrustManager参见BogusTrustManagerFactory,使用serverKeys.jks、clientKeys.jks分别构建服务端和客户端KeyManagers
	private static KeyManager[] getKeyManagers(String keysfile, String password) throws GeneralSecurityException,
			IOException {

		// First, get the default KeyManagerFactory.
		KeyManagerFactory kmf = KeyManagerFactory.getInstance(KEY_MANAGER_FACTORY_ALGORITHM);
		
		// Next, set up the TrustStore to use. We need to load the file into
		// a KeyStore instance.	
		KeyStore ks = KeyStore.getInstance("JKS");
		InputStream in = BogusSslContextFactory.class.getResourceAsStream(keysfile);
		ks.load(in, password.toCharArray());
		in.close();

		// Now we initialise the KeyManagerFactory with this KeyStore	
		kmf.init(ks, password.toCharArray());

		// And now get the TrustManagers
		return kmf.getKeyManagers();
	}


服务端(TLSServer)和客户端(TLSClient)测试代码比较简单,具体请参考源码,在这里有一点需要注意的就是在服务端添加加密过滤器 SslFilter时必须设置为:sslFilter.setNeedClientAuth(true),需要验证客户端证书。

源码中还包括了一个spring版本的TLSServerSpring、TSLClientSpring服务端、客户端测试类。
分享到:
评论
1 楼 林夕_释梦 2015-01-22  
下载连接是啥啊?

相关推荐

    基于 MINA 的 TLS/SSL NIO Socket 实现(二)

    在本篇博文中,我们将深入探讨如何利用Apache MINA库实现基于TLS/SSL的NIO(非阻塞I/O)Socket通信。MINA是一个高度可扩展的网络应用框架,广泛用于构建高性能、高并发的网络应用程序,如服务器端的TCP和UDP服务。...

    Mina实现长连接和短连接实例

    在这个实例中,我们将探讨如何使用Mina实现长连接和短连接。 首先,理解长连接和短连接的概念至关重要。在TCP/IP通信中,短连接(Short Connection)是指一次数据传输完成后立即关闭连接,而长连接(Long ...

    MINA长连接框架实现通讯

    综上所述,MINA长连接框架在实现服务器与Android客户端通讯时,涉及到网络编程、数据传输协议、异常处理、过滤器机制、长连接维护等多个技术要点,开发者需要根据实际需求进行合理的架构设计和优化。通过MINA提供的...

    mina sslfilter大用法

    在Mina中,`SslFilter`实现了SSL/TLS协议,它可以添加到I/O处理器的过滤链中,对进出的数据进行加密解密。`SslFilter`需要配置SSL上下文(SSLContext),该上下文包含了证书、密钥和信任管理器等信息。 **3. 创建...

    基于Apache Mina实现的TCP长连接和短连接实例

    在本文档中,我们将通过具体实例,详细介绍如何使用Apache Mina 2.0实现TCP协议下的长连接与短连接。 #### 二、系统概述 ##### 2.1 系统架构 本系统主要由两个服务端程序与两个客户端程序构成,其中: - **长...

    mina连接 mina心跳连接 mina断线重连

    在本文中,我们将深入探讨Mina的核心概念,包括连接管理、心跳机制以及断线重连策略。 首先,让我们理解"Mina连接"。在Mina中,连接是指客户端与服务端之间建立的通信链路。它支持多种传输协议,如TCP/IP(Socket)...

    mina server开发服务端/客户端代码

    在Mina中,服务端通常通过创建一个Acceptor来监听特定的端口,等待客户端的连接请求。Acceptor会处理连接建立、数据传输和连接关闭等网络事件。服务端的核心组件是IoHandler,它定义了对网络事件的处理方法,如...

    mina双向通信已测试

    **mina双向通信已测试** ...在实际项目中,开发者可以利用Mina实现更复杂的服务,如分布式系统中的通信、实时数据传输等。这个测试项目不仅可以帮助提升技能,还可以作为基础模块,为后续的开发工作提供便利。

    基于MINA2实现的UDP双向通信源码

    本源码是《NIO框架入门(三):iOS与MINA2、Netty4的跨平台UDP双向通信实战》一文的服务端实现(MINA2版),详见:http://www.52im.net/thread-378-1-1.html

    mina实现登录功能

    在这个场景中,我们将讨论如何使用MINA来实现一个简单的登录功能。 首先,理解MINA的基本工作原理至关重要。MINA的核心是IoSession对象,它代表了服务器和客户端之间的持久连接。当客户端连接到服务器时,MINA会...

    使用MINA实现长连接

    1. **Session:** 表示一个网络连接,它是MINA中的基本概念,包含了与远程客户端的连接状态和相关的数据传输信息。 2. **IoHandler:** 是MINA的核心接口,定义了处理网络事件的方法,如连接建立、数据读写、连接...

    Mina长连接短连接实例

    它利用Java NIO库,实现了异步、非阻塞的通信模式,可以在单一线程中处理多个并发连接,大大提升了服务器的并发能力。Minaclient和MinaHost工程正是展示了如何在实际项目中应用这些概念。 在Minaclient工程中,我们...

    socket通信,mina长连接通信

    1. **MINA架构**:MINA基于NIO(非阻塞I/O),利用Selector进行多路复用,可以在单个线程中处理多个连接,提高系统效率。 2. **长连接**:与传统的Socket短连接不同,长连接保持在客户端和服务器之间长时间打开,...

    使用mina框架实现cmpp2.0服务端

    2. **会话建立**:实现CMPP连接的认证机制,包括基于IP地址、端口号或特定的CMPP协议报文的认证过程。 3. **协议解析**:设计CMPP2.0协议的解码器(Decoder)和编码器(Encoder),将原始的字节流转换为业务对象,...

    通信层使用Mina框架实现双机通讯

    在实现双机通讯时,我们通常会使用TCP协议,因为其具有面向连接、可靠传输的特点,适合于需要稳定数据交换的场景。 要使用Mina实现双机通讯,我们首先要创建一个服务器端(Server)和一个或多个客户端(Client)。...

    JAVA NIO MINA2调用大宝CA密码安全套件实现国密SSL安全通道,1.0.1版本,含通信示例代码

    使用方法见:https://blog.csdn.net/upset_ming/article/details/96491058 1. 修改了前一版本中证书验证的bug,支持JDK8的高版本 2. 支持国密SSL双向认证 3. 将过期的国密证书替换为新证书

    Mina+Socket通信

    在Mina与Socket通信的实现中,服务端通常使用Mina来创建一个Acceptor,监听特定端口,等待客户端的连接请求。一旦有连接建立,Mina会自动触发相应的事件处理器,开发者可以在其中处理数据读写。以下是一个基本的...

    mina 实现简单通讯

    在这个“mina 实现简单通讯”的项目中,我们看到了一个基于MINA的基本通信实现,涵盖了服务端和客户端的交互。 首先,MINA的核心组件包括`IoSession`,它是网络连接的抽象,包含了与特定连接相关的所有信息,如输入...

    mina 长连接 客户端+服务端

    在这个"mina 长连接 客户端+服务端"的示例中,我们将探讨如何使用Mina实现长连接以及收发消息的功能。 长连接是网络通信中的一种模式,与短连接相对。短连接在每次通信后都会关闭连接,而长连接则保持连接状态,...

Global site tag (gtag.js) - Google Analytics