HTTP即超文本传输协议(HyperText Transfer Protocol) 具有相当优秀和方便的一面。然而方便带来的是简单,越是简单的东西容易被人利用。HTTP在安全性方面基本完全没有防备,安全性的不足导致HTTP容易被窃听,篡改,以及伪装。
对于这种情况,HTTPS应运而生。在了解HTTPS之前,我们先了解对于HTTP可以有几种可行的方法进行加密。
首先是传输上的,我们无法对传输线路进行完整安全的保护,毕竟互联网是大家的,没有哪条线路是私人拥有的,也没有那么大精力去保护大量线路的加密。因此从传输通道上来说,这个过程的任何位置都可能被窃听。
于是我们转换思路,既然无法保护明文的安全传输,就将明文变为密文,对传输内容加密,即使被监听到了什么内容,监听者无法解密,信息仍是安全的。
HTTP本身没有加密机制,但可以通过接口在发送前进行加密处理。此处介绍和 SSL(Secure Socket Layer,安全套接层)与 TLS(Transport Layer Security,安全层传输协议) 机制对HTTP信息进行加密。
在对 SSL进行讲解之前,我们先来了解一下加密方法。SSL采用一种叫做公开密钥加密(Public-key cryptography) 的加密处理方式。
近代的加密方法中加密算法是公开的,而密钥却是保密的。通过这种方式得以保持加密方法的安全性。
加密和解密都会用到密钥。没有密钥就无法对密码解密,反过来说,任何人只要持有密钥就能解密了。如果密钥被攻击者获得,那加密也就失去了意义。
传统对内容的加密方式就像钥匙和锁,加密算法对其进行加密,也就是锁,而密钥即开锁的钥匙,可以将被加密的内容恢复成明文状态。
于是大体的思路出现了,HTTP报文利用加密算法进行加密,对方利用该加密算法的唯一密钥进行解密,外人对密钥一无所知的情况下对传输途中加密的报文无能为力。
这就是共享密钥加密,也被称为对称密钥加密
但在实际生产生活中,你的接收方必须有一把钥匙,你可能并未接触过你的接收方,你们是第一次通信,也就是说你必须给对方传输一个密钥,你们双方才能都拥有同一个唯一密钥,才能享受共享密钥加密。但这又回到了开始的问题,如果密钥的传输是不安全的,你们后续的传输仍是不安全的。如果密钥的传输无法安全的转交,加密也就失去了意义。还必须设法安全的保管接受到的密钥。
下面介绍有两把密钥的公开密钥加密。
公开密钥加密使用一对非对称的密钥。一把叫做私有密钥(private key),另一把叫做公开密钥(public key)。顾名思义,私有密钥不能让其他任何人知道,而公开密钥则可以随意发布,任何人都可以获得。
使用公开密钥加密方式,发送密文的一方使用对方的公开密钥进行加密处理,对方收到被加密的信息后,再使用自己的私有密钥进行解密。利用这种方式,不需要发送用来解密的私有密钥,也不必担心密钥被攻击者窃听而盗走。
这就像一个投币箱,当你接受任何人的投币时,对方向你投币箱的投币口放入硬币,但这个口只能放入硬币,但不能取出硬币,而你有一把钥匙,只有你能通过钥匙打开投币箱,得到他人给你投的硬币。投入硬币的过程就是他人用你给出的公开密钥加密信息的过程,而信息进入你的投币箱后就是安全的,直到你用私有密钥解密,打开了投币箱的锁,投的钱才完全归你所有。也就是信息解密后你可以正常明文读取。
另外,要想根据密文和公开密钥,恢复到信息原文是异常困难的,因为解密过程就是在对离散对数进行求值,这并非轻而易举就能办到。退一步讲,如果能对一个非常大的整数做到快速地因式分解,那么密码破解还是存在希望的。但就目前的技术来看是不太现实的。
HTTPS 采用共享密钥加密和公开密钥加密两者并用的混合加密机制。若密钥能够实现安全交换,那么有可能会考虑仅使用公开密钥加密来通信。但是公开密钥加密与共享密钥加密相比,其处理速度要慢。
所以应充分利用两者各自的优势,将多种方法组合起来用于通信。在交换密钥环节使用公开密钥加密方式,之后的建立通信交换报文阶段则使用共享密钥加密方式。
通过公开密钥加密解决了共享密钥加密遇到的密钥传输问题,因为共享密钥的效率高于公开密钥加密,因此两者结合,公开密钥加密传输共享密钥加密的密钥,之后所有通信利用共享密钥加密实现。
以上内容即HTTPS的SSL机制解决了HTTP被窃听的问题,下面介绍被篡改和伪装的问题。
我们以前点击一些正常网页的链接时会突然被重定向或转移到某些不良网站的链接上,也就是说,当我们向服务器发送请求时,服务器可能的确收到了,可能被半路拦截了,而后拦截者会伪装成与我们通信的对方身份,强行塞给我们一些不良信息。HTTP只负责进行传输,双方搭上能交流了,HTTP就达成使命了,至于和你交流的人是不是你想要的,HTTP不做判断。也就是说HTTP无法确定通信方。
而SSL采用的证书机制解决了这个问题。
证书由值得信任的第三方机构颁发,用以证明服务器和客户端是实际存在的。另外,伪造证书从技术角度来说是异常困难的一件事。所以只要能够确认通信方(服务器或客户端)持有的证书,即可判断通信方的真实意图。
通过使用证书,以证明通信方就是意料中的服务器。这对使用者个人来讲,也减少了个人信息泄露的危险性。
另外,客户端持有证书即可完成个人身份的确认,也可用于对Web 网站的认证环节。
接收到的内容可能有误
由于 HTTP 协议无法证明通信的报文完整性,因此,在请求或响应送出之后直到对方接收之前的这段时间内,即使请求或响应的内容遭到篡改,也没有办法获悉。换句话说,没有任何办法确认,发出的请求 / 响应和接收到的请求 / 响应是前后相同的。
比如,从某个 Web 网站上下载内容,是无法确定客户端下载的文件和服务器上存放的文件是否前后一致的。文件内容在传输途中可能已经被篡改为其他的内容。即使内容真的已改变,作为接收方的客户端也是觉察不到的。
像这样,请求或响应在传输途中,遭攻击者拦截并篡改内容的攻击称为中间人攻击(Man-in-the-Middle attack,MITM)。
如何防止篡改
虽然有使用 HTTP 协议确定报文完整性的方法,但事实上并不便捷、可靠。其中常用的是 MD5 和 SHA-1 等散列值校验的方法,以及用来确认文件的数字签名方法。提供文件下载服务的 Web 网站也会提供相应的以 PGP(PrettyGood Privacy,完美隐私) 创建的数字签名及 MD5 算法生成的散列值。PGP 是用来证明创建文件的数字签名,MD5 是由单向函数生成的散列值。不论使用哪一种方法,都需要操纵客户端的用户本人亲自检查验证下载的文件是否就是原来服务器上的文件。
浏览器无法自动帮用户检查。
可惜的是,用这些方法也依然无法百分百保证确认结果正确。因为 PGP 和 MD5 本身被改写的话,用户是没有办法意识到的。为了有效防止这些弊端,有必要使用 HTTPS。SSL提供认证和加密处理及摘要功能。仅靠 HTTP 确保完整性是非常困难的,因此通过和其他协议组合使用来实现这个目标。
HTTP+ 加密 + 认证 + 完整性保护=HTTPS
问题再回到HTTPS的加密传输上。之前介绍的两种加密方式相辅相成,已经足够安全了吗?也不是无懈可击,可以想到,建立所有安全通信的基础就是公开密钥中服务器散播出去的密钥,想象如果你是攻击者,唯一可以做手脚的地方就是这里,一旦对方想要建立链接时用了经过攻击者篡改的公开密钥,那么后续一切传输都不是安全的。归根结底,你说有公开密钥向你发送消息,你再用私有密钥解开即可,那么如何证明我收到的一定是你发布的公开密钥呢?比如,正准备和某台服务器建立公开密钥加密方式下的通信时,如何证明收到的公开密钥就是原本预想的那台服务器发行的公开密钥。 或许在公开密钥传输途中,真正的公开密钥已经被攻击者替换掉了。
这是一个类似防伪装和篡改的问题,显而易见我们依然可以引入第三方的证书机制。由 数字证书认证机构(CA,CertificateAuthority) 和其相关机关颁发的公开密钥证书。
我们来介绍一下数字证书认证机构的业务流程。首先,服务器的运营人员向数字证书认证机构提出公开密钥的申请。数字证书认证机构在判明提出申请者的身份之后,会对已申请的公开密钥做数字签名,然后分配这个已签名的公开密钥,并将该公开密钥放入公钥证书后绑定在一起。
服务器会将这份由数字证书认证机构颁发的公钥证书发送给客户端,以进行公开密钥加密方式通信。公钥证书也可叫做数字证书或直接称为证书。接到证书的客户端可使用数字证书认证机构的公开密钥,对那张证书上的数字签名进行验证,一旦验证通过,客户端便可明确两件事:
一,认证服务器的公开密钥的是真实有效的数字证书认证机构。
二,服务器的公开密钥是值得信赖的。
一旦该公开密钥是有合法证书的,那么就能证明这个公开密钥的真实性。下一步问题可能就是如何证明证书是真实有效的了。
此处认证机关的公开密钥必须安全地转交给客户端。使用通信方式时,如何安全转交是一件很困难的事,因此,多数浏览器开发商发布
版本时,会事先在内部植入常用认证机关的公开密钥。
自此,环环相扣的安全保护机制保证了HTTPS的传输加密是安全可靠的。最终一步步防篡改和伪装的源头止步于用户客户端内嵌的认证机关公开密匙,以此来检验服务器发布的公开密匙的合法性,而服务器的公开密匙用于保证共享密匙的安全传输,而共享密匙则对HTTP报文做最初的加密,从而实现HTTPS的安全传输。