一、为什么要HTTPS
HTTP协议因为其轻、小、快、简单,所以在全世界普及开来,各种应用都离不开它。但是随着业务复杂度的提高,HTTP的这些优点逐渐成为了短板。所以就开始各种打补丁,比如因为HTTP是无状态的协议,所以为了管理状态而诞生的Cookie。这篇文章要说的是其中一个为了安全而诞生的超级补丁SSL(HTTPS)。
1. HTTP在安全方面哪儿不行
- 窃听
HTTP使用明文进行传输,因此传输内容可能会被窃听。以太网工作方式是将要发送的数据包发往连接在一起的所有主机。在包头中包括有应该接收数据包的主机的正确地址,因为只有与数据包中目标地址一致的那台主机才能接收到信息包,但是当主机工作在监听模式下的话不管数据包中的目标物理地址是什么,主机都将可以接收到。- 伪装
HTTP协议中不管是请求还是响应都不会对客户端和服务器的身份进行确认。在HTTP协议通信时,任何人都可以发起请求,服务器只要接收到请求,不管对方是谁都会返回一个响应(当然,可以在服务端对IP或者端口进行限制)。因此,可能服务器或者客户端并不是我们想象中的对方。而且,对于无意义的请求服务器也会照单全收,可能会遭遇DoS攻击。- 篡改
对于信息的准确性我们可以用一个专业术语—报文完整性来说明,由于HTTP无法验证通信报文的完整性,因此,在请求或者响应发送之后到接收这段时间内,传输的内容可能已经被篡改(中间人攻击)。
2. HTTPS呢
- 防止被窃听—加密
加密分为两种,首先是对通信的加密,HTTP协议中没有加密机制,但是可以通过外挂的方式对通信进行加密,通过和SSL或TLS的组合使用,可以加密HTTP的通信内容。其次是对内容的加密,在这种情况下,客户端和服务器需要对发送的内容进行加密解密操作。另外,由于该方法不像SSL和TLS一样对整个通信线路进行加密,虽然内容不会被窃听,但是可能会被篡改。此外,加密分为对称加密和非对称加密。HTTPS当然是使用最复杂的混合加密机制(对称加密和非对称加密一起使用)(SSL、TLS、对称和非对称加密稍后会介绍)。- 防止遭遇伪装—证书
借助刚刚提到的SSL,它不仅提供加密处理,还提供了用于确认通信双方身份的东西—证书。证书是由大家都信任的第三方机构颁发的,用来证明服务器或者客户端是实际存在的。- 防止被篡改—摘要
借助与SSL提供的认证、加密和摘要功能,这些功能组合起来可以有效检测传输内容的完整性。当然,HTTP本身就带有MD5和SHA-1等散列值校验的方法,但是并不可靠。
因此,可以说HTTPS就是穿着SSL马甲的HTTP。
二、SSL,TLS,对称加密,非对称加密,证书都是什么鬼
SSL和TLS
TLS是以SSL为原型开发的协议,有时会统一称为SSL协议。
HTTPS并不是应用层的一种新协议,只是普通HTTP协议在接口部分使用SSL(Secure Socket Layer,安全套接层)和TLS(Transport Layer Security,安全传输层)协议而已。
通常,HTTP直接与tcp协议进行通信,当使用SSL时,则HTTP先和SSL通信,再由SSL和TCP进行通信,SSL是独立于HTTP的协议,所以除了HTTP以外,其他应用层协议也可以和SSL配合使用(如SMTP和Telnet)。
对称和非对称加密
这里的对称描述的是加解密的密钥,如果加密和解密密钥相同,则是对称加密,反之则是非对称加密。下面说一下两种加密方式的优缺点(只是针对用在HTTPS协议方面的优缺点),具体的加密算法有很多,感兴趣的推荐看一下《现代密码学趣味之旅》,一本科普一样的密码书,不像其他密码书那样全是数学晦涩难懂。
- 对称加密和非对称加密优缺点
对称加密因为加解密使用的是同一密钥,相对非对称加解密使用不同密钥,对称加密对CPU资源的消耗会更少,速度会更快,更适合大量数据的加密。但是对称加密需要将密钥发送给通信的另一方,如果密钥在传输过程中被截获,那就白忙活了。所以这时候就需要非对称加密发挥优势了,非对称加密可以用来传输对称加密的密钥!- HTTPS混合加密机制
HTTPS当然使用复杂的混合加密机制(对称加密和非对称加密一起使用)。其实对称加密已经够用,只是有一个问题,对称加密的密钥如何发送给通信的另一方。我们把信息装进一个带锁的箱子了,并把箱子发送给另一方,对方如何打开箱子才是问题的关键。这一过程也叫做密钥交换。混合加密机制就是在密钥交换阶段使用非对称加密方式,之后使用对称加密方式进行传输。
证书
即使使用上述的非对称加密方式进行加密,还是有一个问题,那就是无法确认公开的密钥就是货真价实的通信对方的公开密钥。有可能公钥在传输过程中已经被攻击者替换掉了。
为了解决这个问题,证书应运而生。证书也叫公开密钥证书,是由数字证书认证机构(CA,Certificate Authority)和其相关机构颁发的。以下是数字证书认证机构的业务流程:
- 服务器的运营人员向数字证书认证机构提出公钥申请。
- 认证机构在判明申请者的身份之后,对已申请的公钥做数字签名(非对称加密使用私钥进行加密叫数字签名)。
- 认证机构分配这个已签名的公钥,并将该公钥放入公钥证书后绑定在一起。
- 服务器将证书发送给客户端,客户端使用认证机构的公钥解开证书,进行验证。
这里有一个比较棘手的问题,认证机构的公钥如何发送给客户端?一般现在主流浏览器都是在内部植入了认证机构的公钥。
还有一点就是客户端也有证明身份的客户端证书,比如银行的网银网盾。
三、整个过程走一遍
一般面试的时候面试官都喜欢问HTTPS的整个通信步骤。
- 请求由客户端发起。客户端发送Client Hello报文开始SSL通信。报文中包含了SSL的版本,加密组件等信息。
- 服务器收到请求会以Server Hello报文作为应答,报文内容和请求时差不多(经过筛选的)。
- 紧接着服务器再发送一条Certificate报文,报文中包含了证书。
- 服务器活还没干完,还需要发送Server Hello Done报文给客户端,表示SSL握手结束。
- 然后该客户端了,客户端会回应一个Client Key Exchange报文,报文包含用步骤3中公钥加密后的随机密码串。
- 接着客户端继续发送Cipher Spec报文,提示服务器,用步骤5的随机密码串作为密钥加密之后的通信。
- 然后客户端发送Finished报文,表示这次协商结束,是否成功还得看服务器能不能解密该报文。
- 服务器没问题,发送Change Cipher Spec报文。
- 服务器发送Finished。
- SSL连接完成,接下来使用HTTP进行通信。
- 最后由客户端断开连接。发送close_notify报文。