Article Learn

HTTPS原理科普

Post by 明日黄花 at 2016-10-25 16:46:16

注:本文为“小米安全中心”原创,转载请联系“小米安全中心”

上期回顾:浅谈PHP安全开发

0x00 HTTP 和 HTTPS

今年的3·15晚会上有个环节,主持人进行了一个现场实验。现场用户连接了公共WIFI之后,手机APP传输的明文数据就可以被抓取到,其中不乏姓名、手机号、家庭住址等隐私信息[1]

虽然这些信息并非手机APP故意泄露,但信息传输的安全性需要手机APP厂商主动保证,为了实现这一目标,使用HTTPS是最常见的选择之一。

0x01 SSL/TLS

HTTPS是建立在SSL/TLS基础上的,TLS(TransportLayer Security)的前身是SSL(Secure Sockets Layer),目前我们使用的其实都是TLS协议,但是在日常表达中,我们还经常使用SSL这个术语。它可以在不安全的网络通道上,建立起端到端的安全连接,可以防止数据受到窃听和篡改。SSL于1994年由Netscape公司提出,最早便是用于加密HTTP协议的通信数据,但SSL/TLS是与应用层协议无关的,各种应用层协议,都可以和SSL/TLS配合来实现安全通信[2]

应用层协议与SSL/TLS配合主要有两种方式:一种像HTTPS一样,使用独立于HTTP服务(80)的端口(443)来提供SSL/TLS服务;另一种是在明文协议的基础上,通过特定的指令启动SSL/TLS握手,之后再开始传输加密数据,SMTP等协议就是这样做的。

TLS协议主要有两大功能:

  • 加密

  • 认证[3]

加密不用多说,就是保护传输数据的安全,避免3·15晚会上那种信息泄露的事情发生。TLS通过对称密钥来加密通信,这样可以在保证安全的情况下,提供足够的处理速度。现在常见的加密算法是AES,有些旧版本浏览器或者服务器还在使用3DES或者RC4算法进行加密,但这种加密方式已经不再安全了。

TLS的另一大功能就是认证,认证就是确保与你通信的另一端正是他向你声称的那个人,这句话说起来有些拗口,其实很好理解,电话就是一个没有认证机制的通信方式,来电话的对方说他是XX公安局、XX法院,让你把钱汇到某个账户,但我们并没有办法(不涉及第三方,只用电话的情况下)确认它究竟是不是真的XX公安局、XX法院(我们已经知道,这种情况下10000%都不是)。

为了避免如此,我们需要一个机制来验证这件事。认证是通过证书来实现的,证书就像是我们生活中的介绍信,A(用户)本来不认识B(网站所有者),但A认识C(根证书颁发机构,用户的操作系统里预置了一些知名的根证书),当B拿着C的介绍信(根证书颁发机构颁发的证书)出示给A时,A也就相信了B。关于证书,可以参考我们公众号前段时间的文章《证书检测二三事》。有了这两大功能,就基本上可以保证我们使用TLS的安全性了。

0x02 TLS握手

(图片来自CloudFlare对Keyless SSL的介绍[3]

说了这么多,终于进入了正题,我们来说一下TLS握手的过程。

最近有条新闻很火,中国发射了“墨子”号量子科学实验卫星。它的一大功能,就是进行天地间的量子密钥分发实验[4]。量子密钥分发,其实就是在一个“无条件安全”的信道上,通信双方协商对称密钥的过程。而TLS却要在一个不安全的信道上,协商出对称密钥,所以我们要通过以下几步来完成:

1.Client Hello

首先,客户端向服务端发送Client Hello消息,其中含有版本号(TLS 1.0),客户端随机数(Random Bytes)和客户端支持的Cipher Suites列表(图中共17组,列表较长并没有展开)。除此之外,还通过SNI(Server Name Indication)扩展,传输了要访问的服务器域名(sec.xiaomi.com)。标准的TLS握手过程是不涉及域名的,如果在同一服务器上提供多个Web服务的话,服务端就无法出示对应的证书(一般会出示默认证书),而这个默认证书可能和用户请求的域名不符,导致用户浏览器报错。

2.ServerHello

ServerHello的内容简单很多,服务端会从客户端发来的CipherSuite列表中选择一个,生成服务端随机数,一并发给客户端。

3.Certificate 和 Server KeyExchange

在这一步,服务端向客户端发来了证书,还有用证书私钥签名的用于D-H协商的参数。客户端收到之后,首先验证证书是否合法(请继续参考《证书检测二三事》),然后用证书来验证D-H参数的签名,最后生成客户端的D-H参数。如果服务端也需要客户端身份验证,那么此时还会发来Certificate Request消息。

4.Client Key Exchange

客户端把生成好的D-H参数,发送到服务端,如果要求客户端认证的话,客户端会先依次发送Certificate、Client Key Exchange、Certificate Verify三个消息,Certificate Verify消息中含有自Client Hello到上一个消息中所有消息的签名,以便证实客户端确实拥有客户端证书的私钥[5]。

Diffie-Hellman密钥协商算法保证了经过以上两次传输后,客户端和服务端双方都获得了同样的密钥(Premaster secret),利用这个密钥,接下来双方就可以进行对称加密的通信了。

上面所述是D-H密钥协商的过程,还有另一种密钥协商方式,直接使用RSA非对称加密算法进行:在Server Hello之后,服务端只发送证书,并不生成D-H参数,客户端直接生成Premaster secret,并用证书的公钥加密后发给服务端。服务端可以直接用证书的私钥解密。此时双方都有Premaster secret用于后续的对称加密。

0x03 中间人攻击

TLS协议实现了端到端的加密,在网络上抓包只能获得加密过的数据,除非Premaster secret泄露,否则无法解密,这样就防止了被动入侵者的攻击。但是如果有一个入侵者,可以控制双方的通信,那么他能否获得我们的信息呢?

如前文所说,TLS的一大功能是认证,也就是验证了通信对方的身份,这是通过证书来实现的,在握手过程中,客户端应该验证证书的合法性,如果我们不这样做,就给中间人攻击制造了条件。攻击者——也就是所谓的“中间人”——伪装成客户端与服务端通信(在一般场景下,服务端并不对客户端进行认证,这点毫无难度),同时,伪装成服务端与客户端通信。在这种情况下客户端并没有和真正的服务器建立端对端的TLS连接,在中间人那里,客户端和服务器端的通信完全是明文的。

中间人要伪装成服务端,就必须出示一个证书,由于中间人并非服务端证书的合法持有者,所以它的证书要么颁发者有问题(不受信任),要么证书的所有者(CommonName)不对。我们的浏览器,会对此产生提示。

在这种情况下,我们可以主动停止访问此网站,开始排查中间人攻击发生的原因。

而中间人“攻击”也可以为我们所用,在我们开发或者安全检测的过程中,需要拦截浏览器(或者手机客户端)到服务器的HTTPS通信,我们可以用Fiddler[6]或者Charles[7]等Web调试代理软件。它们都有解密HTTPS流量的功能,而这个“解密”功能的原理,就是作为中间人,伪装成远程服务器进行通信。为了让我们的浏览器或者手机App可以“心甘情愿”地被监听,我们要在自己的电脑或者手机上,安装并信任软件生成的根证书。

0x04 结语

随着金融等行业逐渐互联网化,网络信息安全也越来越受重视,了解HTTPS的原理有助于我们更深入地理解和TLS/SSL有关的安全问题和攻防手段。本文的内容只是粗浅地讲解了HTTPS的基本原理,要对HTTPS有更加深入的了解,可以参考以下文章。

—   联系我们   —

新浪微博

公众号