程序用JSSE定制SSL连接

ssl连接  时间:2021-01-23  阅读:()

用JSSE定制SSL连接http://www.yunyo ub ar.c o m/邮件群发

JSSE Java SecuritySocket Extension Java安全套接字扩展是Sun为了解决在Internet上的安全通讯而推出的解决方案。它实现了SSL和TSL传输层安全协议。在JSSE中包含了数据加密服务器验证消息完整性和客户端验证等技术。

通过使用JS SE开发人员可以在客户机和服务器之间通过T CP/IP协议安全地传输数据。这篇文章主要描述如何使用JSSE接口来控制SSL连接。

首先我通过一个简单的客户机服务器程序来介绍如何利用JSSE进行编程。当建立客户端时我们需要配置KeyStore和TrustStore文件这样在程序中我们才可以从客户端的文件系统中加载它们。然后文章将讨论授权和身份验证方面的问题。通过从KeyStore中选择不同的授权客户端程序可以连接到不同的服务器。

在运行JSSE程序前你需要正确安装JSSE。如果你安装了J2SE 1.4 JSSE已经被自动安装并配置好了如果你使用的是其他版本的Java你需要从官方站点上下载并安装JSSE安装过程这里就不再赘述。 由于JSSE是在J2SE 1.4中才成为标准的并且J2SE 1.4中的JSSE和以前的JSSE有一些细微的差别而且文中的例子都是在J2SE 1.4下调试的 因此推荐你使用J2SE 1.4运行这些例子。

在深入介绍JSSE之前让我们来一个简单的客户机服务器程序程序中包含了两个文件 S imp le S S LS erve r和S imp le S S LC lie nt。在运行程序之前你需要配置下面这些KeyStor e和Tres tStor e文件

·一个客户端的KeyStore文件该文件中包含了对Alic e和Bo b的授权。

·一个服务器端的KeyS tor e文件该文件中包含了对server的授权。

·一个名为c lientTrust的客户端TrustS tore文件该文件中包含了对server的授权。·一个名为serverTrus t的服务器端TrustSto re文件该文件中包含了对Alice和Bob的授权。

使用keytoo l可以帮助你创建这些文件该工具在Java的b in目录下 

·一个客户端的KeyStore文件该文件中包含了对Alic e和Bo b的授权。

在命令窗口中输入下面的命令keytoo l-genkey-alias alice-keystore c lientKeys

窗口中会出现下面的提示根据提示输入相应的信息

输入keys tore密码 p ass word

您的名字与姓氏是什么

[Unknown] Alice

您的组织单位名称是什么

[Unknown] Development

您的组织名称是什么

[Unknown] DCQ

您所在的城市或区域名称是什么

[Unknown] ChongQ ing

您所在的州或省份名称是什么

[Unknown] ChongQ ing

该单位的两字母国家代码是什么

[Unknown] CH

CN=Alice,OU=Development,O=DCQ,L=ChongQ ing,S T=ChongQ ing,C=CH正确吗

[否] 是

输入的主密码

如果和keys tore密码相同按回车 

通过相同的方式可以建立对Bob的授权。keytoo l-genkey-alias bob-keystore c lientKeys

注意在名字与姓氏一栏中填写Bob。在完成后可以键入下面的命令来检测是否已经

正确完成了授权。keytoo l-lis t-v-ke ysto re c lie ntKe ys????

·一个服务器端的KeyS tor e文件该文件中包含了对server的授权。

在命令窗口中键入下面的命令keytoo l-genkey-alias s erver-keystore serverKeys

注意将密码设为passwo rd名字与姓氏设定为Server。完成授权后同样可以通过上面提到的命令来检测。

·一个名为c lientTrust的客户端TrustS tore文件该文件中包含了对server的授权。以及一个名为serverTrus t的服务器端TrustSto re文件该文件中包含了对Alice和Bob的授权。keytool-export-alias server-keystore clientKeys -file server.cer

输入keys tore密码 p ass word

保存在文件中的认证keytoo l-export-alias alice-keystore clientKeys -file alice.cer

输入keys tore密码 p ass word

保存在文件中的认证keytoo l-export-alias bob-keystore clientKeys -file bob.cer

输入keys tore密码 p ass word

保存在文件中的认证

这样keytoo l就在当前目录下创建了三个授权文件。然后我们将serve r.cer文件导入到c lientTrust文件中将alice.cer和bob.cer导入到serverTruest文件中keytoo l-import-alias server-keystore c lientTrust -file server.cer

keytoo l-import-alia s alice-keystore serverTrust -file alice.cerkeytool-import-alias bob-keystore serverTrust-file bob.cer

到目前为止在当前目录下包含clientKeys serverKeys clientTrust serverTrust四个文件。完成了KeyStore和Trus tStore的设置后就可以运行例子程序了。首先需要运行服务器程序java-Djavax.net.ssl.keyStore=serverKeys

-Dj avax.net.s s l.ke ySto reP ass word=pa sswo rd

-Djavax.net.s s l.trustS tore#NAME?

-Djavax.net.s s l.trustS torePa sswo rd=password S imp leS S LS erver

在命令行中我们指定了keyS tore属性为s erverKe ys。 由于服务器程序需要获得客户端的授权信息我们指定trustStore为serverTrust。这样S S LS imp leServer就可以验证由S SLS imp leC lient提供的授权信息。当服务器程序成功运行后你会看到下面的提示

SimpleSSLServer running on port 49152????

这时候服务器会等待客户端发出建立连接的申请。如果你希望在另一个端口上运行服务器程序可以在命令中指定-port xxx参数其中xxx是端口号。

然后在另一个命令窗口中运行客户端程序java-Djavax.net.ss l.keyStore=c lientKeys

-Dj avax.net.s s l.ke ySto reP ass word=pa sswo rd

-Djavax.net.s s l.trustS tore=c lientTrust

-Dj avax.net.s s l.trustS torePa sswo rd=pass word S imp leS S LC lie nt

客户端程序会试图向本机的49152端口建立SSL连接。 同样你可以通过-port参数指定端口号也可以通过-host参数指定主机名称。当连接成功后会出现下面的提示信息

C onnected

同时在服务器端会提示用户客户端已经连接成功。

Simp leS S LServer

让我们先来看一下Simp leS S LServer。在main  方法中程序获得了缺省的S SLServerSocketFactory对象然后利用S S LServerSocketFactory创建一个Simp leS S LS erve r对象最后调用s tart  方法启动S imp leS S LS erve r对象。SSLServerSocketFactory ss f=

(S SLServerSocketFactory)S S LServerSocketFactory.getDefault();

SimpleSSLServer server=new SimpleSSLServer(ssf,port);server.s tart();

由于服务器是在一个单独的线程中运行的 main  方法启动了服务器之后就退出了。 s tar t  方法启动了一个新的线程该线程执行r un  方法中的代码。在r un

 方法中创建了一个S SLServerSocket对象然后设定服务器需要进行客户端验证

SSLServerSocket serverSocket=

(S SLServerSocket)serverSocketFactory.createServerSocket(port);serverSocket.setNeedC lientAuth(true);

调用run  方法后程序进入了一个死循环等待客户端的连接申请。循环中的每个Socket对应一个HandshakeCo mp letedListener对象该对象是用来显示客户验证信息中的标识名称distinguished name的 。 Socket的InputStream对象被包装在一个InputDisp layer对象中这个InputDisp layer对象运行在另外一个线程中用来将Socket接收到的数据发送到S ystem.out。下面的代码是S imp leS SLServer中的主循环体while(true) {

String ident=String.valueO f(id++);

//监听连接请求.

SSLSocket socket=(SSLSocket)serverSocket.aclearcase/"target="_blank">ccept();

//通过使用HandshakeCo mp letedListener对象,程序进行授权验证.

HandshakeComp letedListener hcl=new S imp leHandshakeListener(ident);socket.addHandshakeCo mp letedListener(hc l);

InputStream in=socket.getInputStream();new InputDisplayer(ident, in);

}

程序中的Simp leHandshakeListener类实现了HandshakeComp letedListerner接口。在Simp leHandshakeListener类中实现了handshakeComp leted  方法该方法在S S L握手阶段完成后将被JSSE调用。它将显示出客户端的标识名称class S imp leHandshakeListener imp lements HandshakeComp letedListener

{

String ident;

/**

*构造函数.

*/public S impleHandshakeListener(String ident)

{this.ident=ident;

}

/**当SSL握手过程完成后该方法被激活. */public void handshakeCompleted(HandshakeCompletedEvent event)

{

//显示授权信息.try{

X509 C ertific atecert=(X509C ertificate)e ve nt.getPeerC e rtificates()[0];

String peer=cert.getSubjectDN().getName();

System.out.println(ident+":Request from"+peer);

}catch(SS LPeerUnverifiedException pue) {

System.out.println(ident+":Peer unverified");

}

}

}

用红色字体表示的两行代码是这段代码的核心 getPeerCertificates  方法返回一个X509C ertific ated对象的数组。这些X509C ertificated对象创建了客户端的身份标识。在数组中的第一个元素是客户端的验证信息而最后一个通常是CA验证。当我们有了客户端的验证信息后。我们可以得到其中的标识名称并将它传送到Sys te m.o ut。

S imp le S S LC lie nt

S imp le S S LC lie nt类比较简单但是在后面的一些比较复杂的例子中的类会继承该类。在getSLLSocketFacto ry  方法中程序返回缺省的工厂类protected S SLSocketFactory getS S LSocketFactory()throws IOException,GeneralSecurityException

{return(S SLSocketFactory)S S LSocketFactory.getDe fault();

}

在runC lie nt()方法中程序处理了输入参数后获得S S LS ockFacto ry对象调用

connect  方法连接到服务器程序。在connect  方法中程序首先创建一个S SLSocket对象然后调用S S LSocket对象的startHandshang  方法启动和服务器端的握手过程。当握手过程完成后会触发一个HandshakeCo mp letedEvent事件。在服务器端的HandshakeCo mp letedListener对象会处理这个事件。事实上JSSE可以自动启动握手过程但是必须是在第一次有数据通过Socket传输的情况下。 由于在例子程序中直到用户在键盘上输入信息后才会有数据通过Socket传输而我们希望服务器端及时报告连接情况 因此我们用startS hake  方法来手工激活握手过程。public void connect(SSLSocketFactory sf)throws IOException

{socket=(SSLSocket)sf.createSocket(host,port);try{s ocket.startHands hake();

}catch(IOException ioe) {

//握手失败.关闭连接.try{socket.close();

}catch(IOException ioe2) {

//忽略该错误.

}socket=null;throw io e;

}

}

Simp leS SLClient类中的transmit  方法也很简单。首先程序将输入流包装到一个Reader对象中然后将输出流包装到一个Writer对象中最后将数据流输出到Socketboolean done=false;

while(!done) {

String line=reader.readLine();if(line!=null) {wr iter.wr ite(lin e);wr ite r.wr ite('\n');wr iter.flu s h();

}else done=true;

}

定制KeyS tor e和TrustS tore?

还记得我们是如何运行客户端的吗我们需要在命令行中指定keySto re,ke ySto reP as word, trustS tore和trus tSto rePass word参数 以至于整个命令显得过于冗长。事实上你可以在程序中指定KeyS tor e和Trus tS tore后面的例子中将告诉你如何实现这一点。 同时在例子中还会演示如何配置多个S SLSocketFactory对象其中每个S SLS ocketFac tory对象对应不同的KeySto re和Trus tSto re设置。如果没有这种技术在同一个虚拟机上的所有安全连接都只能使用同一个K eyS to re和TrustStore。对于比较小的应用程序这也许不会产生问题但是对于那些比较大的应用程序来说这绝对是一个严重的缺陷。

在下面的例子中我们将使用Custo mTrus tStoreC lie nt来动态定义Ke yStore和Trus tStore。首先让我们先运行一下Custo mTrustS toreC lientjava CustomTrustS toreC lient

为什么运行Custo mTrus tStoreC lie nt时不需要指定KeyS tore和TrustS tore参数呢这是应为在Custo mTrus tStoreC lie nt的代码中指定了KeyS tore C lie ntKe ys和TrustStore C lientTruts以及它们的密钥password 。如果你想使用其他的KeyStore、 TrustS tore或密钥可以使用-ks、 -kspass、 -ts和-tspa ss参数来指定。下

牦牛云(3.5USD/月 )阿里云国际版云服务器 1核1G40G

收到好多消息,让我聊一下阿里云国际版本,作为一个阿里云死忠粉,之前用的服务器都是阿里云国内版的VPS主机,对于现在火热的阿里云国际版,这段时间了解了下,觉得还是有很多部分可以聊的,毕竟,实名制的服务器规则导致国际版无需实名这一特点被无限放大。以前也写过几篇综合性的阿里云国际版vps的分析,其中有一点得到很多人的认同,那句是阿里云不管国内版还是国际版的IO读写速度实在不敢恭维,相对意义上的,如果在这...

新版本Apache HTTP Server 2.4.51发布更新(有安全漏洞建议升级)

今天中午的时候看到群里网友在讨论新版本的Apache HTTP Server 2.4.51发布且建议更新升级,如果有服务器在使用较早版本的话可能需要升级安全,这次的版本中涉及到安全漏洞的问题。Apache HTTP 中2.4.50的修复补丁CVE-2021-41773 修复不完整,导致新的漏洞CVE-2021-42013。攻击者可以使用由类似别名的指令配置将URL映射到目录外的文件的遍历攻击。这里...

GreenCloudVPS($30/年),500G大硬盘VPS,10Gbps带宽

GreenCloudVPS最近在新加坡DC2节点上了新机器,Dual Xeon Silver 4216 CPU,DDR4内存,10Gbps网络端口,推出了几款大硬盘VPS套餐,基于KVM架构,500GB磁盘起年付30美元。除了大硬盘套餐外,还加推了几款采用NVMe硬盘的常规套餐,最低年付20美元。不过需要提醒的是,机房非直连中国,尤其是电信用户ping值感人,包括新加坡DC1也是如此。大硬盘VPS...

ssl连接为你推荐
软银亏损65亿美元日本软银为什么要出售阿里巴巴股票进行套现,将腾讯空间首页QQ空间首页是什么?朱祁钰和朱祁镇哪个好朱高炽是不是被朱瞻基谋杀的?朱祁镇和朱祁钰谁更好海克斯皮肤哪个好联盟海克斯科技和抽皮肤哪个合适看书软件哪个好读书软件哪个好51空间登录51空间,怎么添加啊?怎么登陆?q空间登录QQ空间经常提示要登录?qq空间登录网址如何查询QQ空间登入地址?dns服务器故障DNS服务器老是出错 如何从根本上解决??dns服务器故障DNS服务异常是什么意思
欧洲免费vps vps教程 最便宜虚拟主机 老鹰主机 视频存储服务器 debian7 500m空间 骨干网络 大容量存储器 网站cdn加速 阿里校园 世界测速 美国在线代理服务器 metalink 上海服务器 789 上海电信测速 免费ftp 湖南idc ledlamp 更多