从HTTP到HTTPS

HTTP 自从上世纪90年代随着WEB的诞生而出现的,是所有WEB应用的基础。随着网络购物、电子商务、网上银行等逐渐普及,HTTP本身存在信息窃听与身份伪装等问题,已很难满足人们对于可信安全的通信环境的需求了。如何确保用户隐私与数据不被非法获取,这是HTTPS(HTTP Secure )需要解决的问题。使用HTTPS协议的网站,一般都以https开头而不是http,如:https://tools.ietf.org/html/rfc2246

那么,从数据安全的角度来看,HTTP有哪些不足了?

  • HTTP本身不具备加密功能,因此请求与响应都没有经过加密,而使用的是不加密的明文,因此内容可能会被窃听;
  • 通信时不会验证通信方(client/server)的身份,任何人都可以发送请求,而服务器对于所有请求也照单全收,因此客户端与服务端都有可能被伪装;
  • 在传输数据时,报文可能被篡改或者攻击,无法保证报文的完整性(integrity);这种在请求与数据传输过程中,被攻击者拦截并篡改的攻击方式被称为中间人攻击(Man-in-the-middle attack );

为了解决上述安全问题,HTTPS通过在HTTP之下添加一个安全层SSL/TLS(Transport Layer Security , RFC2246)来实现数据的加密、身份验证以及数据完整性校验:
HTTPS architecture

就是说,HTTPS实际是在TCP/IP的基础上加上了TLS协议,而TLS协议是独立于HTTP协议的,因此除了HTTP之外,其他的应用层协议SMTP,TELNET,EMAIL也同样可以使用TLS来实现安全加密的通信。

HTTPS需要解决的问题

HTTPS需要解决的首要问题是,通信过程请求与响应的加密。我们知道,目前世界上常用的加密方式有两种:一个是对称密钥加密(Symmetric-key algorithm ,加密与解密都使用同一个密钥,因此要确保加密信息的安全,通信双方交换密钥时需要保证密钥不被窃取;另一种是非对称加密(也称为公开密钥加密 ), 加密与解密使用两个不同的密钥,一把公钥(对外公开),一把私钥(需要保存),使用非对称加密,发送方只需使用公钥对数据加密,而接收方则利用自己的私钥对密文进行解密,这样通信双方不用交换密钥,不用担心通信过程中密钥被窃取。

HTTPS实际上同时使用了这两种加密方式来实现安全通信。在通信开始交换密钥时使用的是非对称加密的方式来交换对称加密的密钥;等到密钥交换完毕后,发送通信数据时则利用交换后的密钥来对数据进行加密。

但采用这种混合加密的方式通信还存在一个问题:无法确保非对称加密公开密钥的真实性。比如,某个客户端与服务器建立链接时,如何要证明所接收到的公钥就是服务器发送过来的密钥了,有可能在密钥传递的过程中,公钥已经被攻击者替换成完全不同的一个密钥了。

为了解决上述公钥真实性的问题,需要使用第三方数字认证机构(Certificate Authority )颁布的公钥数字证书 。数字证书是一种身份标识,表明持有者是一个可信的实体。但即便有一个颁发数字证书的CA,也不能完全确保数字证书的持有着就是可信的(CA机构的数字证书有可能被攻击者篡改或者攻破),这样就产生了类似“先有蛋,还是先有鸡”的问题了 。这是另一个需要解决的信任问题了((查看信任链))。回到HTTPS那个公钥问题。HTTPS是如何利用公钥证书进行安全通信的?

  1. 服务器的运营人员向CA提出公开密钥(公钥)的申请;
  2. CA在确认申请人的身份之后,利用非对称加密算法,产生公钥与私钥。私钥做数字签名 ,公钥放入公钥证书一起发送给申请者;
  3. 服务器拿到公钥证书后,在通信时,发送给客户端,以利用公钥进行通信;
  4. 客户端接受到服务器发过来的公钥证书后,会利用保存在本地的数字证书(CA除了需要将数字证书发给服务器之外,还需要发给客户端,为了确保安全,一般浏览器会内置CA的公钥证书)中的公钥验证服务器的数字签名,一旦验证通过,客户端便认为: 一公钥证书的颁发机构是真实合法的;二是服务的身份是可信的。

确保了密钥交换的公钥的真实性后,HTTPS就可以放心的通信了。

HTTPS通信流程

下图HTTPS的通信流程,相比HTTP通信,其主要多了客户端与服务端的握手流程(握手流程也可以参考TLS标准RFC2246 ):

HTTPS Process

  1. 客户端发送ClientHello报文开始SSL通信;报文包含了客户端支持的SSL版本号、加密组件(Cipher suite)列表(包括了加密算法以及密钥长度等);
  2. 服务端可进行SSL通信,则发送ServerHello报文作为应答。和客户端一样,在报文中包含SSL版本以及加密组件(是从接收的客户端中筛选出来的);
  3. 服务端发送包含数字证书的certificate报文;
  4. 最后服务器发送ServerHelloDone告知客户端SSL握手协商结束;
  5. SSL第一次握手结束后,客户端以ClientKeyExchange报文作为回应,报文中包含通信加密中使用的Premaster secret的随机密码串。报文本身会利用公开密钥进行加密处理;
  6. 客户端继续发送ChangeCipherSpec报文,提示服务器,在此报文后的通信会采用Pre-master secret密钥加密;
  7. 客户端发送Finished报文,该报文包含了建立链接至此全部报文的整体校验值。握手协商是否成功,要以服务器是否能正确的机密该报文为判定条件;
  8. 服务器同样发送ChangeCipherSpec报文;
  9. 服务器发送Finished报文;
  10. 服务器和客户端的Finished报文交换完毕后,SSL通信链接就算建立完成了。此后,客户端就会发送HTTP请求;
  11. 应用层协议通信开始,发送HTTP响应;
  12. 最后由客户端断开链接。断开链接时,发送close notify报文(上图做了简化,实际到这一步还需要发送TCP FIN报文关闭TCP链接)。

在上述通信过程中,应用层HTTP发送的数据都会附加一个利用MAC(Message Authentication Code 的报文摘要,MAC用来验证通信数据的完整性。

参考资料