HTTPS实战之单向验证和双向验证

转载自:https://mp.weixin.qq.com/s/UiGEzXoCn3F66NRz_T9crA 原创: 涛哥 coding涛 6月9日算法

做者对https 解释的入目三分啊浏览器

(全文太长,太懒不想看,-_-b 那就直接拉到底部看总结 )安全

前面的文章中,提到了,https是在TCP协议与http之间加了一个控制安全传输的SSL协议,也就是说,直接运行在TCP之上的HTTP是普通的HTTP,运行在SSL/TLS上的HTTP则是HTTPS。这几个协议在计算机网络的OSI七层模型中的位置以下表所示:服务器

层级层名经常使用协议网络

7应用层HTTP/HTTPS、FTP、Socket、Telnet、SSH、SMTP、POP三、DHCP、DNS、NFS、SNMP并发

6表示层XDR、LPP加密

5会话层SSL/TLS、LDAP/DAP、RPCurl

4传输层TCP、UDPspa

3网络层IP、OSPF、ICMP、计算机网络

2数据链路层以太网、令牌环、PPP、PPTP、L2TP、ARP、ATMP

1物理层物理线路、光纤、无线电

 

客户端执行https请求时,须要由TCP协议创建和释放链接。这就涉及TCP协议的三次握手和四次挥手

注意:咱们可能会常常看到“HTTP的三次握手”这个说法,其实这种说法不许确,HTTP是没有什么三次握手的,这个其实指的就是TCP的三次握手。

 

1、TCP的三次握手(不想了解,可跳过)

TCP经过三次握手,创建链接

 
 

第一次:客户端发送一个惟一的数据包(SYNJ)给服务器,请求创建链接

第二次:服务器收到客户端的请求后,生成一个SYN J的回应包(ack J+1)和一个新的数据包(SYN K),发给客户端

第三次:客户端收到服务器返回的两个包后,针对服务器的SYN K包生成一个回应包(ack K+1),并发送给服务器。至此,完成3步握手。这个过程,相似咱们在信号很差的时候打电话的过程:

“喂,能听到我说话吗”

“我能听到,你能听到我吗”

“能听到”

...

注意,这里“能听到”包含了“听到”“听懂”的两层意思。想象一下,你用中文,对方给你回了一个你听不懂的俄文,这个通话也就没有必要进行下去了。

 

2、TCP的四次挥手(不想了解,可跳过)

TCP协议是一个全双工协议(能够同时进行收发),经过四次挥手关闭链接。

 
 

简单理解:

第一步:客户端发送FIN(M)报文给服务器,告诉对方,“个人数据发完了”。

第二步:服务器收到FIN(M)报文后,回给客户端一个ack(M+1)报文,告诉客户端,“好,我知道了”。

第三步:服务器发一个FIN(N)报文给客户端,告诉对方,“个人数据也发完了”。

第四步:客户端回应ack(N+1),告诉服务器,“好,我知道了”,至此,链接结束。

这个过程相似两我的打完电话的结束过程。

A:我说完了

B:哦

B想了一下,也没什么要说的

B:我也说完了

A:好

通话结束,双方挂电话

3、HTTPS单向验证

TCP链接创建好后,对于HTTP而言,服务器就能够发数据给客户端。可是对于HTTPS,它还要运行SSL/TLS协议,SSL/TLS协议分两层,第一层是记录协议,主要用于传输数据的加密压缩;第二层是握手协议,它创建在第一层协议之上,主要用于数据传输前的双方身份认证、协商加密算法、交换密钥。

HTTPS验证过程就是SSL握手协议的交互过程。“HTTPS验证”这个说法其实不许确的,应该是“SSL验证”,这两种说法网上都能看到。

 

 
 

咱们先从简单点的单向验证开始解释:

一步:客户端发起ClientHello

客户端向指定域名的服务器发起https请求,请求内容包括:

1)客户端支持的SSL/TLS协议版本列表

2)支持的对称加密算法列表

3)客户端生成的随机数A

二步:服务端回应SeverHello

服务器收到请求后,回应客户端,回应的内容主要有:

1)SSL/TLS版本。服务器会在客户端支持的协议和服务器本身支持的协议中,选择双方都支持的SSL/TLS的最高版本,做为双方使用的SSL/TLS版本。若是客户端的SSL/TLS版本服务器都不支持,则不容许访问

2)与1相似,选择双方都支持的最安全的加密算法

3)从服务器密钥库中取出的证书

4)服务器端生成的随机数B

第三步:客户端回应

客户端收到后,检查证书是否合法,主要检查下面4点:

一、检查证书是否过时

二、检查证书是否已经被吊销

有CRL和OCSP两种检查方法。CRL即证书吊销列表,证书的属性里面会有一个CRL分发点属性,以下图所示(CSDN的证书),这个属性会包含了一个url地址,证书的签发机构会将被吊销的证书列表展示在这个url地址中;OCSP是在线证书状态检查协议,客户端直接向证书签发机构发起查询请求以确认该证书是否有效。

 
 

三、证书是否可信

客户端会有一个信任库,里面保存了该客户端信任的CA(证书签发机构)的证书,若是收到的证书签发机构不在信任库中,则客户端会提示用户证书不可信。

若客户端是浏览器,各个浏览器都会内置一些可信任的证书签发机构列表,在浏览器的设置中能够看到。

 
 

若是不在信任表中,则浏览器会出现相似下面的警告页面,提示你不安全。(固然,你能够选择继续访问)

 
 

若客户端是程序,例如Java中,须要程序配置信任库文件,以判断证书是否可信,若是没设置,则默认使用jdk自带的证书库(jre\lib\security\cacerts,默认密码changeit)。若是证书或签发机构的证书不在信任库中,则认为不安全,程序会报错。(你能够在程序中设置信任全部证书,不过这样并不安全)。

四、检查收到的证书中的域名与请求的域名是否一致。

若客户端是程序,这一项可配置不检查。若为浏览器,则会出现警告,用户也能够跳过。

证书验证经过后,客户端使用特定的方法又生成一个随机数c,这个随机数有专门的名称“pre-master key”。接着,客户端会用证书的公钥对“pre-master key”加密,而后发给服务器。

第四步,服务器的最后回应

服务器使用密钥库中的私钥解密后获得这个随机数c。此时,服务端和客户端都拿到了随机数a、b、c,双方经过这3个随机数使用相同的DH密钥交换算法计算获得了相同的对称加密的密钥。这个密钥就做为后续数据传输时对称加密使用的密钥。 

服务器回应客户端,握手结束,能够采用对称加密传输数据了。

 

这里注意几点:

一、整个验证过程,折腾了半天,实际上是为了安全地获得一个双方约定的对称加密密钥,固然,过程当中也涉及一些身份认证过程。既然刚开始时,客户端已经拿到了证书,里面包含了非对称加密的公钥,为何不直接使用非对称加密方案呢,这是由于非对称加密计算量大、比较耗时,而对称加密耗时少。

二、对称加密的密钥只在此次链接中断前有效,从而保证数据传输安全。

三、为何要用到3个随机数,1个不行吗?这是由于客户端和服务端都不能保证本身的随机数是真正随机生成的,这样会致使数据传输使用的密钥就不是随机的,时间长了,就很容易被破解。若是使用客户端随机数、服务端随机数、pre-master key随机数这3个组合,就能十分接近随机。

四、什么是信任库和密钥库。信任库前面已经说了,它是用来存放客户端信任的CA的证书。在程序交互中,须要确保你访问的服务器的证书在你的信任库里面。密钥库是用来存放服务器的私钥和证书

五、中间人攻击问题。前面过程说明中,有一点,客户端是验证有问题的时候,是能够选择继续的。对浏览器而言,用户能够选择继续访问;对程序而言,有些系统为了处理简单,会选择信任全部证书,这样就给中间人攻击提供了漏洞。

中间人攻击时,它想办法拦截到客户端与服务器之间的通讯。在客户端向服务器发信息时,中间人首先假装成客户端,向真正的服务器发消息,得到真正的证书,接着假装成服务器将本身的伪证书发给客户端。服务器向客户端发消息时,中间人假装成客户端,接收消息,而后再假装成服务器向客户端发消息。最后验证过程完成后,客户端的真实对称密钥被中间人拿到,而真正的服务器拿到的是中间人提供的伪密钥。后续数据传输过程当中的数据就会被中间人窃取。

 

4、HTTPS双向验证

单向验证过程当中,客户端会验证本身访问的服务器,服务器对来访的客户端身份不作任何限制。若是服务器须要限制客户端的身份,则能够选择开启服务端验证,这就是双向验证。从这个过程当中咱们不难发现,使用单向验证仍是双向验证,是服务器决定的。

通常而言,咱们的服务器都是对全部客户端开放的,因此服务器默认都是使用单向验证。若是你使用的是Tomcat服务器,在配置文件server.xml中,配置Connector节点的clientAuth属性便可。若为true,则使用双向验证,若为false,则使用单向验证。若是你的服务,只容许特定的客户端访问,那就须要使用双向验证了。

双向验证基本过程与单向验证相同,不一样在于:

1)第二步服务器第一次回应客户端的SeverHello消息中,会要求客户端提供“客户端的证书

2)第三步客户端验证完服务器证书后的回应内容中,会增长两个信息

一、客户端的证书

二、客户端证书验证消息CertificateVerifymessage):客户端将以前全部收到的和发送的消息组合起来,并用hash算法获得一个hash值,而后用客户端密钥库私钥对这个hash进行签名,这个签名就是CertificateVerify message

说明:这里关于客户端私钥的使用,网上有不少文章认为:在协商对称加密方案时,服务端先用客户端公钥加密服务器选定的对称加密方案,客户端收到后使用私钥解密获得。首先,对称加密方案就那么几种,逐个试试就能试出来,不必为了这个增长一个客户端和服务端的交互过程。而这里关于CertificateVerify message的说法参考了维基百科关于“Transport Layer Security”一文中"Client-authenticated TLS handshake"的描述。连接:https://en.wikipedia.org/wiki/Transport_Layer_Security#Client-authenticated_TLS_handshake

3)服务器收到客户端证书后:

a)确认这个证书是否在本身的信任库中(固然也会校验是否过时等信息),若是验证不经过则会拒绝链接;

b)用客户端证书中的公钥去验证收到的证书验证消息中的签名。这一步的做用是为了确认证书确实是客户端的

因此,在双向验证中,客户端须要用到密钥库保存本身的私钥和证书,而且证书须要提早发给服务器,由服务器放到它的信任库中。

 

5、总结一下:

一、单向验证中,若是是你客户端,你须要拿到服务器的证书,并放到你的信任库中;若是是服务端,你要生成私钥和证书,并将这两个放到你的密钥库中,而且将证书发给全部客户端

二、双向验证中,若是你是客户端,你要生成客户端的私钥和证书,将它们放到密钥库中,并将证书发给服务端,同时,在信任库中导入服务端的证书。若是你是服务端,除了在密钥库中保存服务器的私钥和证书,还要在信任库中导入客户端的证书

三、再次强调,使用单向验证仍是双向验证,是服务器决定的。

四、https的验证过程,不论是单向仍是双向,只有四步,网上不少关于https验证过程的文章中,写了来来回回七八上十步。要真是这样,访问一个https地址,时间全花在了交互上了。



做者:神仙苏醒
连接:https://www.jianshu.com/p/119c4dbb7225
来源:简书
简书著做权归做者全部,任何形式的转载都请联系做者得到受权并注明出处。
 
3次握手以后就开始创建ssl通道。

SSL握手:
1.客户单发送hello,这个hello里面有:我是IE浏览器,我支持什么算法des等,SSL/TLS协议版本,随机数A。
2.server回hello包,选择一个算法des(加密数据使用), server回证书(证书有server的公钥),随机数B
3.客户端验证证书,随机数C,用公钥加密,发送证书。
4. 服务器验证证书,服务端用私钥解密获得C,客户端和服务端都有abc3个随机数了。使用abc3个随机数生成数据对称加密密钥。如今密钥和加密算法都选择好了,模式变动,后面的数据都开始加密。

随机数是在第一个请求就开始传输了,非对称加密(客户端用证书公钥加密随机数C服务端用证书私钥解密随机数C)。数据加密要密钥和加密算法对称加密

客户端模式变动:就是以前没有加密,后面的数据包都要加密了,你去解密。服务端模式变动:就是以前没有加密,后面的数据包都要加密了,你去解密。

相关文章
相关标签/搜索