时间进入到2017年,细心的人在浏览器地址栏中会发现,经常浏览的网站都是https打头,最左边也有绿色的安全锁。其实全站https时代已经来临。2014年百度完成了全网https的切换,2015年淘宝、天猫页面全部https访问,苹果公司要求2016年底iOS APP实现https信息传输。众多大厂都不遗余力地推进全面https,提升安全性,这对普通的用户和移动应用开发者有何影响,需要理解和注意什么,本篇来做简单的介绍,了解https带来的安全性和其中的证书验证。
一、HTTPS的安全性体现在哪
HTTP(超文本传输协议,Hyper Text Transfer Protocol)是我们浏览网站信息传输最广泛的一种协议。HTTPS(Hyper Text Transfer Protocol over Secure Socket Layer)相比HTTP增加了一个S,就是安全的(Secure),这个安全体现在什么地方呢?http中的信息是明文传输的,也就是说很容易被监听、截获和篡改;具体来说在http中常用的post和get方法,也是我们在网站上注册、登录帐号时要使用的请求方法,在网站页面不做保护处理的情况下,帐号密码这些信息都将明文的在网络中传输;对于我们浏览的页面内容,也都以字符串的形式被轻松的看到。
使用Fiddler软件,将自己手机连接代理,看看哪些网站或应用还在用http,还在传输着什么。
HTTPS则是在原有的应用层协议HTTP之下,传输层TCP之上,增加了安全套接字层(SSL),来实现信息的安全传输,提供了:
(1)数据加密: 传输的数据是经过加密的
(2)身份认证: 通过证书确认网站的真实性,在启用双向认证时,可确认用户的合法性
(3)内容完整性: 防止内容在传输过程中被篡改
二、HTTPS安全性的基础
HTTPS的安全性离不开SSL协议,理解SSL协议的实现离不开数字证书和非对称加密。这里不会详细介绍SSL协议的实现过程,而是让人能简单理解SSL如何利用数字证书,实现其数据加密和身份认证的功能。
对称加密
加密者和解密者共享密钥,加密者用共享密钥将明文变为密文,解密者用共享密钥将密文变为明文;一般相比非对称加密效率更高,但要求双方提前共享密钥。常见的有AES,DES等。
非对称加密
加解密需要密钥对实现,密钥对包括公钥(Public Key)和私钥(Private Key),将明文用公钥加密,私钥解密,或者用私钥加密,公钥解密。常见的有RSA ,ECC等。注意一般将公钥对外发布,大家都能获得,但私钥只有网站拥有者或特定的用户拥有;而且效率相比对称加密低,运算量大,时间更长。
数字摘要
是将任意长度的输入数据,经过单项哈希后,产生固定长度的输出数据。这么做的一个好处是能将大量的输入信息转换成较小的固定长度的信息。另外单项哈希保证了无法通过输出的摘要数据还原原始的输入数据;而且不同的输入几乎不可能产生相同的数字摘要。常见的摘要算法如SHA,MD5等。
注意的是网上常说的用MD5加密,那一般是不能解密的,因此不能算一种正常的加解密方法。
数字签名:
类似于手写签名,证明是经过你本人确认的,无法抵赖。具体就是利用私钥对原始信息的数字摘要进行加密形成数字签名,与原始信息一起发送给别人。对于接收信息的人,由于公钥能公开获取到,因此对收到的数字签名用公钥解密,再和收到的原始信息的数字摘要进行比对,就能确认是不是私钥的拥有者发送的内容,而且能确认中间有没有被人修改。
前面提到非对称加密的运算量大,时间长,因此数字签名都是对大量传输的信息产生数字摘要后进行加密。
数字证书
是一串身份信息按照指定的格式排列后,包含证书颁发机构进行数字签名的数据。常见的数字证书格式X.509 V3,存储到文件上一般一种为不含私钥的DER格式,以cer或者crt为文件后缀名,另一种为包含私钥的PKCS格式,以pfx或者p12为后缀。
数字证书中包括(不是全部):
(1)数字证书持有者身份信息 网站就包括所对应的URL或IP
(2)该证书拥有者对应的该证书公钥
(3)证书颁发者信息
(4)证书颁发者用私钥对证书持有者身份信息和公钥的签名 使用的摘要和签名算法
证书的验证:
1.两级证书:直接由权威或可信任(自己可设定是否信任)机构颁发给用户的证书
因此有权威机构一个证书(根证书),颁发给用户的一个证书
验证过程是使用颁发者的公钥,采用要验证的证书(后面称用户证书)中说明的签名算法,解密签名,对比根据用户证书上的持有者信息等计算出的数字摘要,看是否一致。
换种描述的说法:
(1)用户证书里有:
a.用户信息UInfo
b.签名用到的摘要算法H,和加解密算法S
c.用颁发者私钥签名的用户信息摘要S(H(UInfo)) (就是用户信息数字摘要H(UInfo),按一定格式编码后,私钥加密后获得S(H(UInfo)) )
d.颁发者信息
(2)验证用户证书
a.根据用户证书里的颁发者信息找到颁发者证书,获取颁发者公钥;
b.再用用户证书里说明的加解密算法S解密签名S(H(UInfo)) ,得到H(UInfo)'
c.根据用户证书中的摘要算法H,自己重新计算用户信息摘要,得到H(UInfo)
d.对比两次的计算结果H(UInfo)'和H(UInfo),如果相同则验证通过。
(3)颁发者证书的验证
需要在电脑预置或自己安装根证书,也就是颁发者的证书,作为认证的起点。
2.证书链的验证
首先证书颁发机构(CA)的根证书,可以签发子CA的证书,CA和子CA都可以审核注册者信息,然后为用户颁发证书。那么从CA到子CA,再到用户证书,构成了证书链。他的验证可以仿照两级证书的验证,一步步往上追,直到用户自己安装的根证书
现在再来看HTTPS中SSL保障安全传输的简单流程:
(1)首先用户在浏览器中发起HTTPS连接请求时,先从网站(服务端)获取了其证书;
(2)浏览器验证了网站证书有效性后,再对比证书中的URL或IP信息和实际访问的URL或IP是否一致;
(3)都正确后再利用证书中的公钥信息,建立安全的信息传输通道;(简单来说,浏览器可以用公钥加密一个共享密钥给服务端,因为只有服务端有私钥。详细的SSL连接建立流程比这里复杂的多,但基本原理类似)
(4)如果客户端将自己的证书发给网站,网站也可以确认用户的合法性
最后说明下HTTPS带来的性能和流量的损失。首次访问网站(服务端),建立SSL链接,客户端需要获取服务端的证书链,验证证书的有效性。这里证书链一般情况下就至少两个证书1K多的数据量,而如果没设置HTTP长连接,那么会导致每次访问请求都会产生握手连接过程,都会大的流泪消耗。好消息是目前一般的Android网络开发库,采用HTTP1.1,默认开启了Keep-Alive设置,但是要注意平衡好超时时长。