澳门新葡亰平台游戏网站SSL+socket 详解-概念

澳门新葡亰平台游戏网站 3

至于SSL的原理和介绍在英特网早原来就有大多,对于Java下选用keytool生成证书,配置SSL通讯的学科也超多。但一旦大家不可以预知亲自入手做三个SSL
Sever和SSL
Client,也许就长久也不能够深入地驾驭Java情况下,SSL的通讯是怎么兑现的。对SSL中的各样概念的认识也说不许会只限于能够运用的档次。本文通过组织叁个简易的SSL
Server和SSL Client来说解Java景况下SSL的通讯原理。

[TOC]

一、 SSL概述

SSL契约使用数字证书及数字签字举行双端实体会认知证,用非对称加密算法举办密钥协商,用对称加密算法将数据加密后进行传输以有限支撑数据的保密性,并且通过计算数字摘要来验证数据在传输进度中是或不是被曲解和冒领,进而为机警数据的传导提供了一种安全保证手腕。

SSL左券提供的劳务重要有:
1)认证客户和服务器,确认保证数据发送到精确的顾客机和服务器
表明客户和服务器的合法性,使它们能够确信数据将被发送到精确的顾客机和服务器上。客商机和服务器皆有分别的识别号,这几个分辨号由公开密钥进行编号,为注解客户是或不是合法,SSL公约供给在握手沟通数据时开展数字作证,以此保障客户的合法性。
2)加密数据以免守数据中途被盗取
SSL左券所接受的加密本领既有对称密钥才干,也许有公开密钥本事。在客商机和服务器进行数据交流前,交流SSL最初握手消息,在SSL握手新闻中接受了各样加密技巧对其举行加密,以管教其机密性和数量的完整性,并且用数字证书实行甄别,这样就足以堤防违法顾客进行破译。
3)维护数据的完整性,确定保障数据在传输进程中不被转移
SSL左券利用Hash函数和秘密分享的法子提供音信的完整性服务,创建客商机和服务器之间的安全通道,使具有通过SSL合同管理的事务在传输进度中能全体安然无恙正确科学的到达指标地。

SSL种类布局:
SSL合同坐落于TCP/IP合同模型的网络层和应用层之间,使用TCP来提供一种保证的端到端的安全服务,它是客商/服务器应用之间的通讯不被攻击抓取,况且平昔对服务器进行认证,还足以采纳对顾客拓宽验证。SSL种类结构如图1所示。

首先大家先想起一下健康的Java
Socket编制程序。在Java下写二个Socket服务器和客商端的事例依然比较简单的。

一、HTTPS 身份验证介绍

二、SSL类别结构:

SSL协议坐落于TCP/IP左券模型的互连网层和应用层之间,使用TCP来提供一种有限帮忙的端到端的安全服务,它是顾客/服务器应用之间的通讯不被攻击抓取,况兼始终对服务器进行认证,还足以选取对客户扩充验证。
在SSL通讯中,首先利用非对称加密调换音信,使得服务器获得浏览器端提供的相辅而行加密的密钥,然后利用该密钥实行报纸发表进程中国国际信资集团息的加密和解密。为了确定保障消息在传递进度中向来不被窜改,能够加密HASH编码来作保消息的完整性。SSL通信进度,如图2所示。
诚如情况下,当客商端是保密消息的传递者时,顾客端不须要数字证书验证本人身份的愚直,如电子银行的利用,顾客须要将团结的账号和密码发送给银行,由此银行的服务器须求安装数字证书来注解本身身价的可行。在一些应用中,服务器端也亟需对顾客端的身价实行求证,那时候顾客端也急需设置数字证书以管教通信时服务器能够辨别出顾客端的地位,验证进程看似于服务器身份的证实进度。

服务端很简单:侦听8080端口,并把顾客端发来的字符串重返去。以下是服务端的代码:

1. HTTPS 原理

HTTPS(Hyper Text Transfer Protocol over Secure Socket
Layer),一句话来说正是加了安全注解的 HTTP,即HTTP + SSL;大家知晓 HTTP
通信时,假设客商端C
央浼服务器S,那么能够透过网络抓包的样式来获取音讯,以致足以上行下效伏务器 S
端,来骗取与 C
端的报导新闻;那对网络使用在安全球的加大特不利;HTTPS肃清了这一个标题。

三、SSL Socket双向认证的落到实处

SSL
Socket通讯是对Socket通信的进展。在Socket通讯的底蕴上增添了一层安全性尊敬,提供了越来越高的安全性,包涵身份验证、数据加密以至完整性验证。
SSL Socket双向认证实现技巧: JSSE(Java Security Socket
Extension),它完成了SSL和TSL(传输层安全)公约。在JSSE中带有了多少加密,服务器验证,新闻完整性和顾客端验证等本事。通过采取JSSE,可以在顾客机和服务器之间通过TCP/IP协议安全地传输数据。为了达成消息证实:

package org.bluedash.tryssl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Server extends Thread {
    private Socket socket;
    public Server(Socket socket) {
        this.socket = socket;
    }
    public void run() {
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintWriter writer = new PrintWriter(socket.getOutputStream());
            String data = reader.readLine();
            writer.println(data);
            writer.close();
            socket.close();
        } catch (IOException e) {

        }
    }
    public static void main(String[] args) throws Exception {
        while (true) {
            new Server((new ServerSocket(8080)).accept()).start();
        }
    }
}
HTTPS 与 HTTP 的区别

1)HTTPS 的服务器需求到 CA 申请证书,以证实本身服务器的用途;

2)HTTP 音讯是堂皇冠冕传输,HTTPS 消息是密文字传递输;

3)HTTP 与 HTTPS 的暗许端口区别,前面一个是 80 端口,前面一个是 443 端口;

可以说 HTTP 与 HTTPS 是截然两样的连接格局,HTTPS
集结了加密传输,居民身份评释,更加的安全。

劳务器端需求:

1、KeyStore: 其中保存服务器端的私钥
2、Trust KeyStore: 其中保存客户端的授权证书

客商端也特简单:向服务端发起倡议,发送贰个”hello”字串,然后拿走服务端的回来。上边是顾客端的代码:

2. HTTPS 身份验证流程

client 向 server 发送实际的作业 HTTPS 诉求以前,会先与 server
举办两次握手,相互印证身份:

拉手的流程图:

澳门新葡亰平台游戏网站 1

HTTPS 身份验证握手流程图

一种解释:

1)顾客端诉求服务器,发送握手音信

2)服务器再次来到客商端自身的加密算法、数字证书和公钥;

3)客户端验证服务器端发送来的数字证书是不是与本地受信任的证书相关消息一致;借使不周边则顾客端浏览器提醒证书不安全。纵然注明通过,则浏览器会采纳本人的随机数算法产生二个任意数,并用服务器发送来的公钥加密;发送给服务器;这里如若有人经过攻击得到了那个消息,这也没用,因为她从没解密此段新闻所急需私钥;验证通过的网址在浏览器地址栏的侧面会有一云浮锁的标志;

3)服务器解密获得此随机数,并用此随机数作为密钥采纳对称加密算法加密一段握手消息发送给浏览器;

4)浏览器收到消息后解密成功,则握手甘休,后续的音讯都因此此随机密钥加密传输。

以上是服务端认证的气象,假若服务端对寻访的顾客端也会有认证供给,则顾客端也必要将和睦的证书发送给服务器,服务器认证不通过,通信甘休;原理同上;

除此以外,平日在传输进程中为了防御音讯窜改,还大概会使用音信摘要后再加密的艺术,以此保障音信传递的精确。

另一种解释表达:

  1. 客商端发起叁个 https 的呼吁,把自家扶助的一文山会海 Cipher
    Suite(密钥算法套件,简单称谓Cipher)发送给服务端。

  2. 服务端,选择到顾客端具有的 Cipher
    后与自个儿扶植的比较,假设不援助则一而再一而再断开,反之则会从当中选出一种加密算法和HASH算法,以注脚的款式重返给顾客端
    证书中还含有了:公钥、颁证机构、网址、失效日期等等。

  3. 顾客端收到服务端响应后会做以下几件事:

    3.1 验证证书的合法性

发布证书的机构是不是合法与是或不是过期,证书中包涵的网址地址是还是不是与正在访谈的地址同样等


证书验证通过后,在浏览器之处栏会加上一把小锁(每家浏览器验证通过后的唤起不一致等
不做研商卡塔尔(قطر‎

3.2 生成自由密码


若是证件验证通过,可能客户接纳了不授信的申明,那时浏览器会生成一串随机数,然后用证件中的公钥加密。

3.3 HASH握手音信

​ 用一发端预定好的 HASH 格局,把握手新闻取 HASH 值, 然后用随机数加密
“握手消息 + 握手消息 HASH 值(签名)” 并同步发送给服务端。

​ 在此边之所以要取握手新闻的 HASH
值,主若是把握手新闻做八个签署,用于注解握手音信在传输进度中从不被篡改正。

  1. 服务端获得顾客端传来的密文,用自身的私钥来解密握手音讯抽出随机数密码,再用随便数密码
    解密 握手新闻与HASH值,并与传过来的HASH值做比较确认是或不是相仿。

​ 然后用随机密码加密一段握手新闻(握手消息+握手消息的HASH值 卡塔尔给客商端

  1. 客商端用随机数解密并计算握手音讯的 HASH,如若与服务端发来的 HASH
    一致,那时握手进程停止,之后全体的通讯数据将由事情发生前浏览器生成的随机密码并利用对称加密算法举办加密,因为那串密钥独有客户端和服务端知道,所以尽管中间央求被拦住也是没有办法解密数据的,以此有限援助了通讯的安全。
  • 非对称加密算法:RubiconSA,DSA/DSS
    在客商端与服务端相互验证的长河中用的是对称加密
  • 对称加密算法:AES,RC4,3DES
    顾客端与服务端互相印证通过后,以随机数作为密钥时,就是对称加密
  • HASH算法:MD5,SHA1,SHA256 在料定握手新闻未有被窜改时

澳门新葡亰平台游戏网站,客商端必要:

1、KeyStore:其中保存客户端的私钥
2、Trust KeyStore:其中保存服务端的授权证书

密钥和授权证书的变型方法:
选拔Java自带的keytool命令,在指令行生成。
1、生成服务器端私钥kserver.keystore文件
keytool -genkey -alias serverkey -validity 1 -keystore
kserver.keystore
2、依据私钥,导出服务器端安全表明
keytool -export -alias serverkey -keystore kserver.keystore -file
server.crt
3、将服务器端证书,导入到顾客端的Trust KeyStore中
keytool -import -alias serverkey -file server.crt -keystore
tclient.keystore
4、生成顾客端私钥kclient.keystore文件
keytool -genkey -alias clientkey -validity 1 -keystore
kclient.keystore
5、依照私钥,导出客商端安全申明
keytool -export -alias clientkey -keystore kclient.keystore -file
client.crt
6、将客户端证书,导入到服务器端的Trust KeyStore中
keytool -import -alias clientkey -file client.crt -keystore
tserver.keystore

扭转的文本分为两组,服务器端保存:kserver.keystore tserver.keystore
顾客端保存:kclient.keystore tclient.kyestore。

客商端采取kclient.keystore中的私钥实行多少加密,发送给服务端,服务器端接纳tserver.keystore中的client.crt证书对数据解密,假如解密成功,证明消息来源可信的客商端,进行逻辑管理;
服务器端选取kserver.keystore中的私钥实行多少加密,发送给顾客端,顾客端应用tclient.keystore中的server.crt证书对数码解密,要是解密成功,评释新闻来源可靠的劳动器端,举行逻辑处理。借使解密失利,那么声明音讯来源错误。不开展逻辑管理。

SSL Socket双向认证的安全性:
(1)能够保险数量传送到准确的服务器端和客商端。
(2)能够制止音信传递进度中被偷取。
(3)幸免音讯在传递进度中被校正.。

在系统运维中或者出现以下景况:
(1)
服务器端、客商端都有着精确的密钥和鹰潭证书,此时服务器端和客商端能够扩充正规通讯。
(2)
客商端的密钥和平安注明不科学,那时劳动器端和客商端不能开展常规通讯。
(3)
客商端未具有密钥和平安注解,当时服务器端和顾客端也不能张开常规通讯。

package org.bluedash.tryssl;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class Client {
    public static void main(String[] args) throws Exception {
        Socket s = new Socket("localhost", 8080);
        PrintWriter writer = new PrintWriter(s.getOutputStream());
        BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
        writer.println("hello");
        writer.flush();
        System.out.println(reader.readLine());
        s.close();
    }
}

二、windows 情形下布署 tomcat HTTPS

要么找 CA 授信部门颁发证书,要么本人给本人颁证书(不受信赖的HTTPS)

上面大家在 windows 上配备 tomcat 的HTTPS 访谈

把服务端运转起来后,实践客户端,我们将获取”hello”的回来。

1. 生成密钥库 keystore

首先使用 JDK 的 keytool 命令,生成 keystore,在 cmd 命令行情势下施行:

keytool -genkey -alias uzipi.com -keyalg RSA -keystore 1024 -validity 365 -keystore d:/server.keystore -keypass Cs123456 -storepass Cs123456

-genkey     表示要生成密钥
-keyalg     指定密钥算法,这里指定为 RSA 算法。
-keysize    指定密钥长度,默认 1024 bit,这里指定为 2048 bit。
-sigalg     指定数字签名算法,这里指定为 SHA1withRSA 算法。
-validity   指定证书有效期,这里指定为 365 天。
-alias      指定生成的密钥库的别名,这里是 uzipi.com
-keystore   指定密钥库存储位置,这里设定的是 d:/server.keystore
-keypass    密钥口令
-storepass  密钥库口令

正是那样一套轻易的互连网通讯的代码,大家来把它改动成选用SSL通讯。在SSL通讯左券中,大家都知情首先服务端必需有二个数字证书,当客商端连接到服务端时,会赢得那一个评释,然后客商端会判别那么些注解是或不是是可相信的,假若是,则调换信道加密密钥,实行通讯。假设不相信任这一个评释,则总是战败。

2. 配置 Tomcat

就此,大家率先要为服务端生成三个数字证书。Java情形下,数字证书是用keytool生成的,那么些证件被存放在store的概念中,正是证书客栈。大家来调用keytool命令为服务端生成数字证书和保存它应用的证书仓库:

2.1 将 server.keystore 文件移动到 汤姆cat 根目录下

​ 为何要运动到 汤姆cat 根目录下吧?因为 Tomcat
运行时优先扫描当前根目录。

keytool -genkey -v -alias bluedash-ssl-demo-server -keyalg RSA -keystore ./server_ks -dname "CN=localhost,OU=cn,O=cn,L=cn,ST=cn,C=cn" -storepass server -keypass 123123
2.2 配置 server.xml 文件

​ 进入 ${TOMCAT_BASE}/conf,编辑 server.xml 文件,依照 汤姆cat
官方网址的提示,大家能够找到 port="8443"<Connector>
标签注释,解开注释改善内容,
也能够直接复制如下内容(自己改密码),参加到 server.xml 文件:

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
            maxThreads="150" scheme="https" secure="true"
            keystoreFile="server.keystore" keystorePass="Cs123456"
            clientAuth="false" sslProtocol="TLS" />
  • keystoreFile 属性值,填写我们无独有偶创制的 server.keystore
    的文本(借使身处了别的目录下,要求钦点路径)
  • keystorePass 属性值,填写在此以前创立的密钥库密码

那样,我们就将服务端证书bluedash-ssl-demo-server保存在了server_ksy那几个store文件个中。有关keytool的用法在本文中就不再多废话。实施上边的指令获得如下结果:

2.3 配置项目的 web.xml

布置 webapps 目录中的项目,找到 WEB-INF/web.xml 文件,增加如下内容:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>SSL</web-resource-name>
        <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>
Generating 1,024 bit RSA key pair and self-signed certificate (SHA1withRSA) with a validity of 90 days
        for: CN=localhost, OU=cn, O=cn, L=cn, ST=cn, C=cn
[Storing ./server_ks]

3. 运行 Tomcat,使用 Https + 8443 端口情势访问项目

用 https + 8443 端口格局访谈项目,会开采与事情未发生前普通 http + 8080
端口形式访谈的界别:浏览器地址栏前边多了不安全的警示。因为是大家丹舟共济发布的注解,所以是不被别的机构信赖的。

然后,改变我们的服务端代码,让服务端使用那几个注解,并提供SSL通信:

三、linux 情况下安插 tomcat HTTPS

linux 上的安顿与 windows 蒙受的计划是相符的。

package org.bluedash.tryssl;

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

import javax.net.ServerSocketFactory;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;

public class SSLServer extends Thread {
    private Socket socket;

    public SSLServer(Socket socket) {
        this.socket = socket;
    }

    public void run() {
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintWriter writer = new PrintWriter(socket.getOutputStream());

            String data = reader.readLine();
            writer.println(data);
            writer.close();
            socket.close();
        } catch (IOException e) {

        }
    }

    private static String SERVER_KEY_STORE = "/Users/liweinan/projs/ssl/src/main/resources/META-INF/server_ks";
    private static String SERVER_KEY_STORE_PASSWORD = "123123";

    public static void main(String[] args) throws Exception {
        System.setProperty("javax.net.ssl.trustStore", SERVER_KEY_STORE);
        SSLContext context = SSLContext.getInstance("TLS");

        KeyStore ks = KeyStore.getInstance("jceks");
        ks.load(new FileInputStream(SERVER_KEY_STORE), null);
        KeyManagerFactory kf = KeyManagerFactory.getInstance("SunX509");
        kf.init(ks, SERVER_KEY_STORE_PASSWORD.toCharArray());
        context.init(kf.getKeyManagers(), null, null);
        ServerSocketFactory factory = context.getServerSocketFactory();
        ServerSocket _socket = factory.createServerSocket(8443);
        ((SSLServerSocket) _socket).setNeedClientAuth(false);

        while (true) {
            new SSLServer(_socket.accept()).start();
        }
    }
}

1. 生成密钥库 keystore

(1)cd 转向到 tomcat 主目录,实践命令生成 keystore 文件

keytool -genkey -alias uzipi.com -keyalg RSA -keypass Cs123456 -storepass Cs123456 -keystore server.keystore -validity 3600

施行命令之后,将会在tomcat主目录下生成 server.keystore 文件;

(2)根据 keystore 文件发出的评释诉求,向 CA 申请服务器数字证书:

keytool -export -trustcacerts -alias uzipi.com -file server.cer -keystore server.keystore -storepass Cs123456

试行命令之后,将会在tomcat主目录下生成 server.cer 文件;

(3)将音讯中央签发的服务器证书 server.cer 导入到 server.keystore
文件:

keytool -import -trustcacerts -alias uzipi.com -file server.cer -keystore server.keystore -storepass Cs123456

能够阅览,服务端的Socket筹算安装专业余大学大增添了,增添的代码的效果重大是将证件导入并打开应用。其余,所利用的Socket形成了SSLServerSocket,其余端口改到了8443(那几个不是挟持的,仅仅是为着遵守习于旧贯)。其它,最根本的一点,服务端证书里面包车型地铁CN一定和服务端的域名统一,大家的申明服务的域名是localhost,那么我们的顾客端在接连服务端时必然也要用localhost来一而再,不然根据SSL协议正式,域名与证件的CN分歧盟,表明这些注明是不安全的,通讯将不能符合规律运作。

2. 生成顾客端证书

(1)为了保险客商端证书能够如愿导入到 IE 和 Firefox
浏览器,须将证书格式为 PKCS12,命令如下:

keytool -genkey -v -alias clientAlias -keyalg RSA -storetype PKCS12 -validity 3600 -keystore client.p12 -storepass clientStorePass -keypass clientKeyPass

实施命令之后,将会在tomcat主目录下生成 client.p12 文件;

有了服务端,大家本来的客商端就不能运用了,应当要走SSL左券。由于服务端的证书是大家精诚团结生成的,未有别的受信任机构的签订,所以顾客端是力无法及注解服务端证书的有用的,通讯必然会退步。所以大家需求为顾客端创设一个保留全数信赖证书的货仓,然后把服务端证书导进那一个库房。这样,当客户端连接服务端时,会发掘服务端的注解在温馨的深信列表中,就足以健康通讯了。

3. 让服务器信赖客商端证书

双向 SSL
认证,服务器须要信任客商端证书,因而要把客商端证书加多为服务器的亲信认证。
由于不能够一贯将 PKCS12 格式的评释导入,要先把客商端证书导出为三个独门的
CER 文件,命令如下:

keytool -export -alias clientAlias -keystore client.p12 -storetype PKCS12 -storepass clientStorePass -rfc -file client.cer

推行命令之后,将会在tomcat主目录下生成 client.cer 文件;

然后将 client.cer 导入到服务器的证书库
server.keystore,增加为叁个亲信证书:

keytool -import -v -file client.cer -keystore server.keystore -storepass Cs123456

施行后,认证就已增添至 keystore 中了。

之所以以往大家要做的是生成二个顾客端的注明宾馆,因为keytool无法仅生成叁个赤手仓库,所以和服务端同样,我们依然生成叁个证书加八个储藏室(客商端证书加旅社):

4. keytool 的其余命令选项

(1)通过list命令查看服务器的证书库,能够看看多个输入,三个是服务器证书,一个是受信任的客商端证书:

keytool -list -keystore server.keystore -storepass Cs123456

(2)删除证书命令

keytool -delete -alias myKey -keystore server.keystore -storepass Cs123456
keytool -genkey -v -alias bluedash-ssl-demo-client -keyalg RSA -keystore ./client_ks -dname "CN=localhost,OU=cn,O=cn,L=cn,ST=cn,C=cn" -storepass client -keypass 456456

5. 修改 tomcat 配置

修改 conf/server.xml 文件,配置 <Connector> port="8443"

<!-- Define a SSL HTTP/1.1 Connector on port 8443 This connector uses the JSSE configuration, when using APR, the  connector should be using the OpenSSL style configuration described in the APR documentation -->
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"   
    maxThreads="150" scheme="https" secure="true"
    clientAuth="false" sslProtocol="TLS" 
    keystoreFile="server.keystore" keystorePass="Cs123456"
    truststoreFile="server.keystore" truststorePass="Cs123456" />
  • clientAuth="true",双向认证;
  • clientAuth="false",单向认证;

结果如下:

6. 重启 tomcat,访问应用

执行 ./bin/startup.sh 命令,访问 https://127.0.0.1:8443
(你和煦的地方State of Qatar 。

单向认证相关的配置到此甘休。假设还索要配备双向认证,继续往下看。

server.xml 文件中的 clientAuth="true",设置为双向认证,展开Firefox 菜单:编辑->首选项->高级->加密->查看证书->你的证书,将
client.p12 导入到 IE 中,依据 Firefox 提醒完成报到 tomcat 首页;

Generating 1,024 bit RSA key pair and self-signed certificate (SHA1withRSA) with a validity of 90 days
        for: CN=localhost, OU=cn, O=cn, L=cn, ST=cn, C=cn
[Storing ./client_ks]

7. 双向认证,让服务器 SSL 证书拿到代码

if(request.isSecure()) { //如果是SSL通信
    Java.security.cert.X509Certificate[] certs = 
 (java.security.cert.X509Certificate[])request.getAttribute("javax.servlet.request.X509Certificate");
    if(certs!=null && certs.lengtt>0) {
        subjectDN="Certificates found";
    }
}

应用java拆解解析证书可获得证书中顾客消息:

issue=certs.getIssuerDN().toString();   //证书签发者
subject=certs.getSubjectDN().getName(); //证书所有者
after=certs.getNotAfter().toString();   //证书起效时间
before=certs.getNotBefore().toString(); //证书到期时间
version=Integer.toString(certs.getVersion());   //证书版本
serialno=certs.getSerialNumber().toString();    //证书序列号

参照文章:

http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html
tomcat7.0 ssl配置

http://wenku.baidu.com/view/e7b22df0f90f76c661371a6f.html
Tomcat SSL 配置

接下去,大家要把服务端的证书导出来,并导入到顾客端的旅舍。第一步是导出服务端的证书:

keytool -export -alias bluedash-ssl-demo-server -keystore ./server_ks -file server_key.cer

实行结果如下:

Enter keystore password:  server
Certificate stored in file <server_key.cer>

然后是把导出的证件导入到客商端证书旅舍:

keytool -import -trustcacerts -alias bluedash-ssl-demo-server -file ./server_key.cer -keystore ./client_ks

结果如下:

Enter keystore password:  client
Owner: CN=localhost, OU=cn, O=cn, L=cn, ST=cn, C=cn
Issuer: CN=localhost, OU=cn, O=cn, L=cn, ST=cn, C=cn
Serial number: 4c57c7de
Valid from: Tue Aug 03 15:40:14 CST 2010 until: Mon Nov 01 15:40:14 CST 2010
Certificate fingerprints:
         MD5:  FC:D4:8B:36:3F:1B:30:EA:6D:63:55:4F:C7:68:3B:0C
         SHA1: E1:54:2F:7C:1A:50:F5:74:AA:63:1E:F9:CC:B1:1C:73:AA:34:8A:C4
         Signature algorithm name: SHA1withRSA
         Version: 3
Trust this certificate? [no]:  yes
Certificate was added to keystore

好,希图职业做完了,大家来撰写客商端的代码:

package org.bluedash.tryssl;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;

public class SSLClient {

    private static String CLIENT_KEY_STORE = "/Users/liweinan/projs/ssl/src/main/resources/META-INF/client_ks";

    public static void main(String[] args) throws Exception {
        // Set the key store to use for validating the server cert.
        System.setProperty("javax.net.ssl.trustStore", CLIENT_KEY_STORE);

        System.setProperty("javax.net.debug", "ssl,handshake");

        SSLClient client = new SSLClient();
        Socket s = client.clientWithoutCert();

        PrintWriter writer = new PrintWriter(s.getOutputStream());
        BufferedReader reader = new BufferedReader(new InputStreamReader(s
                .getInputStream()));
        writer.println("hello");
        writer.flush();
        System.out.println(reader.readLine());
        s.close();
    }

    private Socket clientWithoutCert() throws Exception {
        SocketFactory sf = SSLSocketFactory.getDefault();
        Socket s = sf.createSocket("localhost", 8443);
        return s;
    }
}

能够看出,除了把一些类成为SSL通讯类以外,客商端也多出了选用信赖证书货仓的代码。以上,大家便成功了SSL单向握手通讯。即:顾客端验证服务端的证书,服务端不表明顾客端的评释。
上述就是Java情形下SSL单向握手的全经过。因为大家在客商端设置了日记输出等级为DEBUG:

System.setProperty("javax.net.debug", "ssl,handshake");

于是大家得以看出SSL通信的全经过,这一个日记能够帮助我们更实际地领会通过SSL左券建构互连网连接时的全经过。
结合日志,我们来看一下SSL双向认证的全经过:
澳门新葡亰平台游戏网站 2
第一步:
顾客端发送ClientHello音信,发起SSL连接央浼,告诉服务器自身扶持的SSL选项(加密方法等)。

*** ClientHello, TLSv1

其次步: 服务器响应央求,回复ServerHello音信,和客商端确认SSL加密方法:

*** ServerHello, TLSv1

其三步: 服务端向客商端发布温馨的公钥。

第四步: 客商端与服务端的协通沟通完结,服务端发送ServerHelloDone音信:

*** ServerHelloDone

第五步:
客户端使用服务端赋予的公钥,创制会话用密钥(SSL证书认证完毕后,为了抓好质量,全部的音信交互作用就或许会利用对称加密算法),并因而ClientKeyExchange新闻发给服务器:

*** ClientKeyExchange, RSA PreMasterSecret, TLSv1

第六步:
客商端公告服务器改造加密算法,通过ChangeCipherSpec音信发给服务端:

main, WRITE: TLSv1 Change Cipher Spec, length = 1

第七步: 顾客端发送Finished音讯,告知服务器请检查加密算法的变动央求:

*** Finished

第八步:服务端确认算法改动,再次回到ChangeCipherSpec新闻

main, READ: TLSv1 Change Cipher Spec, length = 1

第九步:服务端发送Finished音信,加密算法生效:

*** Finished

那么如何让服务端也证实顾客端之处,即双向握手呢?其实相当轻松,在服务端代码中,把这一行:

((SSLServerSocket) _socket).setNeedClientAuth(false);

改成:

((SSLServerSocket) _socket).setNeedClientAuth(true);

就足以了。可是,相同的道理,现在服务端并未相信顾客端的评释,因为客商端的注解也是友好生成的。所以,对于服务端,必要做同样的行事:把顾客端的证书导出来,并导入到服务端的证书旅馆:

keytool -export -alias bluedash-ssl-demo-client -keystore ./client_ks -file client_key.cer
Enter keystore password:  client
Certificate stored in file <client_key.cer>

keytool -import -trustcacerts -alias bluedash-ssl-demo-client -file ./client_key.cer -keystore ./server_ks
Enter keystore password:  server
Owner: CN=localhost, OU=cn, O=cn, L=cn, ST=cn, C=cn
Issuer: CN=localhost, OU=cn, O=cn, L=cn, ST=cn, C=cn
Serial number: 4c57c80b
Valid from: Tue Aug 03 15:40:59 CST 2010 until: Mon Nov 01 15:40:59 CST 2010
Certificate fingerprints:
         MD5:  DB:91:F4:1E:65:D1:81:F2:1E:A6:A3:55:3F:E8:12:79
         SHA1: BF:77:56:61:04:DD:95:FC:E5:84:48:5C:BE:60:AF:02:96:A2:E1:E2
         Signature algorithm name: SHA1withRSA
         Version: 3
Trust this certificate? [no]:  yes
Certificate was added to keystore

完了了注明的导入,还要在客商端要求参加一段代码,用于在接连时,顾客端向服务端出示本身的申明:

package org.bluedash.tryssl;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.security.KeyStore;
import javax.net.SocketFactory;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;

public class SSLClient {
    private static String CLIENT_KEY_STORE = "/Users/liweinan/projs/ssl/src/main/resources/META-INF/client_ks";
    private static String CLIENT_KEY_STORE_PASSWORD = "456456";

    public static void main(String[] args) throws Exception {
        // Set the key store to use for validating the server cert.
        System.setProperty("javax.net.ssl.trustStore", CLIENT_KEY_STORE);
        System.setProperty("javax.net.debug", "ssl,handshake");
        SSLClient client = new SSLClient();
        Socket s = client.clientWithCert();

        PrintWriter writer = new PrintWriter(s.getOutputStream());
        BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
        writer.println("hello");
        writer.flush();
        System.out.println(reader.readLine());
        s.close();
    }

    private Socket clientWithoutCert() throws Exception {
        SocketFactory sf = SSLSocketFactory.getDefault();
        Socket s = sf.createSocket("localhost", 8443);
        return s;
    }

    private Socket clientWithCert() throws Exception {
        SSLContext context = SSLContext.getInstance("TLS");
        KeyStore ks = KeyStore.getInstance("jceks");

        ks.load(new FileInputStream(CLIENT_KEY_STORE), null);
        KeyManagerFactory kf = KeyManagerFactory.getInstance("SunX509");
        kf.init(ks, CLIENT_KEY_STORE_PASSWORD.toCharArray());
        context.init(kf.getKeyManagers(), null, null);

        SocketFactory factory = context.getSocketFactory();
        Socket s = factory.createSocket("localhost", 8443);
        return s;
    }
}

经过比对单向认证的日记输出,大家能够开掘双向认证时,多出了服务端认证客商端证书的手续:

*** CertificateRequest
Cert Types: RSA, DSS
Cert Authorities:
<CN=localhost, OU=cn, O=cn, L=cn, ST=cn, C=cn>
<CN=localhost, OU=cn, O=cn, L=cn, ST=cn, C=cn>
*** ServerHelloDone

*** CertificateVerify
main, WRITE: TLSv1 Handshake, length = 134
main, WRITE: TLSv1 Change Cipher Spec, length = 1

在 @*** ServerHelloDone@ 从前,服务端向客商端发起了索要注脚的央浼@*** CertificateRequest@ 。
在顾客端向服务端发出 @Change Cipher Spec@
央浼早前,多了一步客商端证书认证的进度 @*** CertificateVerify@ 。
客商端与服务端相互印证证书的风貌,可参看下图:

澳门新葡亰平台游戏网站 3

参谋资料

1. Change Cipher Spec
Protocol
2. SSL & TLS Essentials: Securing the
Web

You can leave a response, or trackback from your own site.

Leave a Reply

网站地图xml地图