知识点
- HTTPS 是什么?HTTP有哪些缺点?
- SSL、TLS为啥总是被放到一起,有什么区别?
- SSL、TLS历史背景。
- SSL的加密细节,加密算法了解。
- SSL的加密流程。
TLS/SSL 工作机制
在了解SSL细节之前,我们需要先讲解加密方法:公开密钥加密 和 共享密钥加密。
共享/公开密钥加密
共享密钥加密加密是通信双方持有同一把钥匙加解密信息,所以这种加密方式也叫做对称密钥加密或者共享密钥加密。
共享密钥最大的问题是钥匙传输给对方的过程中有可能遭到劫持,一旦传输密钥遭到劫持,共享密钥加密的方式就相当于作废了。
中间人攻击只需要拿到密钥,双方传输加密报文的时候拦截请求数据并且伪造自己的数据,就可以同时“剽窃”双方向的敏感信息。
为了处理这个问题,需要使用公开密钥加密对于共享密钥加密对加密方式进行了改进。
改进方式很简单那就是把钥匙换成一把只能用于加密,这把钥匙可以公开对外使用,而另一把只能用于解密,只有服务端的私钥可以解开公开密钥加密的信息,外部无法通过公钥破解。
如果能在短时间内快速的进行因式分解,那么全世界所有的密码都是透明的。 有时候解密不一定是无法破解,而是破解的代价在现实上“不可能”,比如需要花费上千年的时间破解一串密码,等到破解那时候。。。。可能被破解的资源都没了。
公开密钥加密的最大特点是加密和解密的钥匙并不是同一把,两边对于密文的加解密方式不一样,所以这样的加密方式也别叫做 非对称密钥加密。
混合加密
HTTPS并不是完全使用公开密钥加密或者共享密钥加密,而是通过两种加密混合的方式进一步提升安全。
共享密钥的问题在于密钥泄露的安全性问题,而公开密钥加密因为加解密的钥匙不是同一把,需要花费更多的操作运算和验证。
HTTPS在设计的过程中基于安全和速度的考虑,最终的决定是在连接握手的过程中使用非对称密钥加密确保安全,在服务器非对称加密验证通过之后,会返回稍后需要共享对称加密的密钥信息。在握手完成之后,在确保安全的前提之下, 使用对称加密的密钥进行共享对称加密的信息交互。
需要注意这里提到的加密认证是单向认证,也就是说只会验证服务端的真实可靠性,服务端无法准确保证客户端是可靠的(但是可以确保传输是安全的)。
客户端认证只在特殊的服务上会用到,大部分服务更多使用服务端单向认证,因为多数服务就是设计给所有人都可以访问的。
数字证书加密
混合加密的方式看起来很靠谱和安全,但实际上依然存在问题,那就是无法证明公开密钥本身的真实性,为了理解这一点我们可以回顾共享密钥加密的描述图,在其中展示了攻击者在密钥传输的过程中盗取共享密钥的行为。
如果把这一行为替换为盗取公开密钥,则可以在客户端请求的时候劫持替换为攻击者自己的非对称加密密钥,之后的共享加密同样也是,可以被轻易获取。
具体的攻击过程如下:
- 服务端在数字证书认证成功之后,和客户端进行公开密钥加密认证,此时中间人截取到公开密钥,伪造出自己的公钥(同时拥有自己的私钥)以及用于共享之后传给SSL认证的客户端。
- 客户端拿到被替换的服务端公钥认证,将共享加密的密钥通过伪造的密钥加密之后,回传给服务端。
- 中间人继续劫持掉客户端请求,通过自己的私钥解密之后,用自己伪造的共享加密密钥,利用上一次服务端传递的真实公钥,加密之后传给服务端。
- 服务端拿到被加密的假的的共享密钥之后,解密获得中间人的共享加密密钥。
- 原本
在这样的攻击手段之下,为了保证客户端请求的服务器的真实性,采用第三方权威机构认证是合理的。
CA证书
为了解决这个问题,所采用的方式是通过第三方机构数字认证机构(CA,Certificate Authority),加入CA之后整个验证过程如下:
- 服务端运营请求数据认证机构申请公开密钥,数字机构验证请求者的数字认证信息,然后分配给已经签名的密钥,然后把公开密钥放入到公钥证书绑定一起返回。
- 服务器将颁发的数字认证机构的公钥证书发给客户端,使用公开密钥加密通信。这一步也叫数字认证机构传递证书。
- 客户端使用数字证书认证公开密钥,对于数字签名认证,认证通过可以获取两个信息
- 认证服务器的公开密钥的数字认证机构是否合法真实。
- 被认证的服务器公开密钥是否真实。
注意认证机关的公开密钥必须安全传给客户端,否则哪怕是数字认证本身还是有可能被篡改。为了规避这一个问题,许多浏览器会在安装的时候认证机构的公开密钥。
但是浏览器自带证书也有安全隐患,那就是数字认证机构遭到入侵后果不堪设想,历史上也真发生过类似事件。
EVSSL证书
证书的作用是保证服务端的公开密钥的真实性,也可以验证服务器是否真实存在。
EV SSL 证书是基于国际标准的认证指导方针颁发的证书。主要的作用是提高网站的认可度。
有时候浏览器如果带HTTPS会出现绿色打勾的字样,这样做是提醒用户网站合法性。
客户端证书
客户端证书通常会出现在安全性要求极高的特殊业务当中,同时客户端本身需要支持SSL证书的开销,但是SSL的客户端证书只能证明请求的机器是没有问题的,但是无法保证
机构信誉
作为数字认证的机构一旦出现问题后果不堪设想,在过去曾经出现过数字认机构被黑客破解的情况,其对于SSL的公信力是一次巨大打击,
OpenSSL
OpenSSL 是可以让用户自己构建一套认证机构的开源程序,但是仅能作为本地使用。
如果出现外部访问,浏览器会提示“无效证书”等内容。
HTTPS的通信步骤
下面依照SSL的的交互步骤介绍HTTPS的通信过程。
这部分内容在[[《图解HTTP》- 用户身份认证]]里面的SSL流程一致,但是对于细节做了进一步扩展。
第一次握手:确认支持SSL
- 客户端发送Client Hello 开始SSL通信,
HandShake
就是握手的意思,报文中指定SSL版本和加密组件(加密算法和密钥长度等)。服务器支持SSL通信,返回Server Hello
应答,报文加入SSL的版本以及加密信息。服务器的加密组件需要根据客户端支持的加密通信方式筛选。
- Version: 客户端支持的TLS协议版本
- Random: 客户端生成的随机数,随后用于生成 master secret
- SessionID: 会话 ID,如果不为空,表示客户端想重用该会话
- CipherSuites: 客户端支持的加密套件列表,在 SessionID 为空时必须携带
- CompressionMethods: 客户端支持的压缩算法列表
- Extensions: 扩展内容
第二次握手:服务端证书验证
- 接收到客户端SSL版本以及加密组件信息,服务器支持SSL通信如果则返回
Server Hello
应答。 - 服务器发送
Certificate
报文,报文包含公开密钥证书,证书必须是 x.509 标准格式,包含服务端公钥、服务端域名、签发方信息、有效期等信息。 - 服务器发送
Server Hello Done
表示SSL最初的握手协商已经结束。
第三次握手:客户端确认
- 客户端按照
Client Key Exchange
回应,这个报文会在通信加密中使用Pre-mastersecret
的随机串,这个随机串第一步部分的第三个步骤已经偷偷完成加密了。 - 客户端继续发送
Change Cipher Spec
报文,告知服务器后续使用Pre-master secret
密钥加密通信(共享对称加密)。 - 客户端发送
Finished
报文。在这个报文中包含整个报文回应的校验和,客户端确认是否完成要根据服务器能否认识这一段加密报文为主。
第四次握手:服务端确认
- 服务器同样发送
Change Cipher Spec
报文,表示自己认识客户端的加密信息。 - 服务器同样发送
Finished
报文,SSL连接建立完成。
至此SSL连接建立完成,通信将会受到协商好的共享密钥加密保护,应用层开始进行通信。应用层通信,服务端进行响应。
断开连接
- 客户端主动断开链接。断开连接会发送
close_notify
的报文。之后发送TCP FIN
报文关闭通信。
注意在整个SSL四次握手的过程中,应用层发送数据时会附加一种叫做 MAC(Message Authentication Code)
的报文摘要。MAC 能够查知报文是否遭到篡改,从而保护报文的完整性。
最后是书中给的一幅图,了解整个加密过程(个人感觉画的一般,有点乱)
CBC 模式(Cipher Block Chaining)又名密码分组链接模式。此模式会把一个明文模块加密处理之后的下一个明文进行XOR运算。重叠之后对于运算结果进行加密处理。 对于第一个明文进行加密之后,
最后是IETF 关于TLS协议原文的握手步骤,看起来比较抽象,但是实际上算是最权威的交互信息了,图片展示是TLS1.2的协议原文内容:
除开最后一次的数据交互之外,服务端和客户端需要四次握手才能完成。
也就是说从TCP连接到SSL连接完成,一共需要9次握手才能最终建立一个安全连接,所以其效率可想而知。
为什么不全用HTTPS
- 纯文本通信对比的加密通信消耗更多资源
- 非敏感的HTTPS使用意义和价值不大
- 购买证书的开销和成本。CA证书购买开销不菲,但是对于现在的很多服务器来说是一笔必要开支,虽然有时候非常不合算。