Skip to content

Latest commit

 

History

History
59 lines (38 loc) · 6.9 KB

Node中如何搭配使用SSL与TLS.md

File metadata and controls

59 lines (38 loc) · 6.9 KB

原文地址

作者:Florian Rappl Almir Bijedic

在这篇文章中,我将通过一个实际的例子来演示如何在你的express服务器上添加一个用Let's Encrypt生成的证书。

但仅仅通过HTTPS还不足以达到保护我们的网站或者是应用的目的。我们还需要与我们通信的服务器建立加密的连接。我们将能够看到激活SSL/TLS层的可能性即使SSL/TLS层默认是关闭的

让我们开始简短的回顾一下HTTPS当前的情况。

无处不在的HTTPS

HTTP2规范在2015年5月作为RFC7540文件被发布出去,这也意味着从这个节点开始http2成为了标准的一部分。这是一个具有里程碑意义的事件,现在我们可以把所有的服务器都升级到HTTP2,其中比较关键的几个方面就是与HTTP1.1的向后兼容以及切换不同协议的协调机制。虽然标准没有强制要求加密通信,但当前还没有任何浏览器支持未加密的http2.这就从另一方推广了HTTPS。最终在任何地方都拥有https。

我们的执行栈应该长什么样子呢?站在浏览器上运行的网站的视角可以粗略的描绘出下面的层次结构

  1. Client browser
  2. HTTP
  3. SSL/TLS
  4. TCP
  5. IP

HTTPS只不过就是SSL/TLS层之上的HTTP协议。因此所有的HTTP规则依然适用。那这些复加的层给我们带来了什么呢?这里列出多种优势;我们可以通过密钥和证书进行鉴权;保证一定的隐私性和保密性,因为连接是通过非对称加密的方式建立的;保持数据的完整性:在传输过程中数据不会被篡改。

一个比较常见的误区就是认为使用SSL/TLS需要更多的资源以及拖慢服务器的速度。这已经不再是事实,我们也不需要什么专门的加密设备。即使是Google,SSL/TLS层的占比也少于CPU负载的1%。此外,HTTPS的网络开销相较于HTTP也会低于2%。总而言之,因为一点点网络开销而放弃HTTPS是没有意义的。

image

最新的TLS版本为TLS1.3(当时是2018年1月25日),TLS是SSL的继承者,在SSL3.0版本提供出来。从SSL到TLS的变化就是排除了互操作性。然而基本步骤还是没有变化。我们拥有三种不同的加密通道。首先是证书链的公钥基础设施,其次是为密钥交换提供公钥加密,最后是对称加密。此时,我们就拥有了对于数据传输的加密条件。

TLS会在一些重要的操作上使用hash,理论上可以使用任何的哈希算法,但强烈推荐使用SHA2或者一个更健壮的算法。SHA1作为标准已经很长时间但最近会被废弃(当时是2018年1月25日)。

HTTPS也越来越受到客户端的关注。隐私性和安全性问题一直都存在,但是随着在线可访问的数据和服务逐渐增多,人们开始越来越关心这些问题。这里有一个很有用的浏览器插件叫做“HTTPS Everywhere”,它加密了我们同大多数网站的通信

image

插件作者意识到许多网站只是部分支持HTTPS。插件允许我们为那些只部分支持HTTPS的站点重写请求,或者,我们也可以选择性的屏蔽HTTP请求

基础通信

证书验证过程包含了证书签名的验证以及过期时间的验证,我们还需要验证它是否能链接到一个可信的根证书。最后我们还需要检查证书是否被撤销。会有专门的机构来颁发证书,万一其中有证书被泄漏,那所有来自上述机构的证书都会被吊销。

下面的序列图描绘出了HTTPS的握手过程,但在这里主要描述SSL/TLS的握手过程

  1. Client Hello:首先客户端发送Client Hello消息,消息中会包含一个客户端生成的随机数Random1,客户端支持的加密套件(Support Ciphers)以及SSL的版本等信息。
  2. Server Hello:服务端向客户端发送Server Hello的消息,在第一步中,客户端会向服务端传过来一些加密套件信息,服务端会根据该信息确定出一份加密套件,这个套件决定了后续加密和生成摘要时具体使用哪些算法,另外服务端这一块还会生成一份随机数Random2.此时在客户端及服务端各自生成了随机数,这两个随机数会在后续生成对称密钥时用到。
  3. Certificate:这一步是服务端将证书下发给客户端,让客户端验证自己的身份,如果身份验证通过,就取出证书中的公钥。
  4. Server Key Exchange:如果非对称加密使用的是DH算法,这一步服务端就会发送自己所使用的DH参数,如果采用的是RSA算法,则不需要这一步。
  5. Certificate Request:这一步是服务端要求客户端上报证书,这一步是可选的,对于安全性高的场景会用到
  6. Server Hello Done:通知客户端Server Hello过程结束。
  7. Certificate Verify:客户端受到下发的证书后,会通过CA来验证该证书的合法性,验证通过则取出证书中的服务端公钥,再生成一个随机数Random3,在用服务端公钥非对称加密Random3生成PreMaster-key
  8. Client Key Exchange:这一步是说客户端会将上一步生成的PreMaster-key传给服务端,服务端收到这个key,再用私钥解出这个PreMaster-Key得到客户端生成的Random3,至此,客户端以及服务端都拥有3个随机数,Random1, Random2, Random3,两边再根据同样的算法就可以生成一份秘钥,握手结束后应用层的数据就是使用该密钥进行对称加密的。那为什么要使用三个随机数呢?这是因为TLS/SSL握手过程的数据都是明文传输的,多个随机数种子来生成密钥不容易被暴力破解出来。
  9. Change Cipher Spec(Client):这是一条事件消息,这一步是客户端通知服务端之后再发送的消息都通过前面协商出来的密钥进行加密。
  10. Encrypted Handshake Message(Client):这一步对应Client Finish消息,客户端将前面的握手信息生成摘要再用协商好的密钥加密,这是客户端发出的第一条加密消息,服务端收到后会用密钥进行解密,能解出来说明前面协商出来的密钥是一致的。
  11. Change Cipher Spec(Server):这也是一条事件消息,用于服务端通知客户端之后的消息都会使用加密
  12. Encrypted Handshake Message(Server):这一步对应的是Server Finish消息,服务端也会把握手过程的消息生成摘要再用密钥加密,这是服务端发出的第一条加密消息,客户端收到后会用密钥解密,能解密出来,说明之前协商出来的密钥是一致的。
  13. Application Data:到这一步,双方已经协商出了同一份密钥,所有应用层的数据都会用这个密钥进行加密然后通过TCP传输

image