HTTP (超文本传输协议)协议被用于在 Web 浏览器和网站服务器之间传递信息, HTTP 协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了 Web 浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此, HTTP 协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息。
HTTP 是一种无状态协议。无状态是指客户机和服务器之间不需要建立持久连接,这意味着当一个客户端向服务器发出请求,然后服务器返回响应,连接就被关闭了,在服务器端不保留连接的有关信息, HTTP 遵循请求/应答模型。
HTTP 协议由于是明文传输,主要存在三大风险:窃听风险、篡改风险、冒充风险。
中间人可以获取到通信内容,由于内容是明文,所以获取明文后有安全风险。
中间人可以篡改报文内容后再发送给对方,风险极大。
比如你以为是在和某宝通信,但实际上是在和一个钓鱼网站通信。
对称加密:
采用单密钥系统的加密方式,同一个密钥可以同时用作信息的加密和解密,加密和解密所用的密钥是相同的,加密速度快,效率高。
非对称加密:
用两个密钥进行加密和解密,一个是公钥一个是私钥,缺点是运算速度非常慢。
可以通过公钥对明文进行加密,形成密文,通过密钥对密文进行解密,形成明文。同理,也可以通过密钥对明文进行加密,公钥对明文进行解密,但是公钥是公开的,也就明文也随之公开了。
为了解决HTTP
协议的安全缺陷,需要使用另一种协议:安全套接字层超文本传输协议HTTPS
。为了数据传输的安全,HTTPS
通过SSL/TLS
(安全套阶层)来加密数据包,SSL
再通过数字证书来验证服务器的身份,以此来实现数据在客户端到服务器之间的传输安全。
一般我们认为安全的通信需要包括以下四个原则: 机密性、完整性,身份认证和不可否认。
★ 机密性:即对数据加密,解决了窃听风险,因为即使被中间人窃听,由于数据是加密的,他也拿不到明文;
★ 完整性:指数据在传输过程中没有被篡改,不多不少,保持原样,中途如果哪怕改了一个标点符号,接收方也能识别出来,从来判定接收报文不合法;
★ 身份认证:确认对方的真实身份,即证明“你妈是你妈”的问题,这样就解决了冒充风险,用户不用担心访问的是某宝结果却在和钓鱼网站通信的问题;
★ 不可否认: 即不可否认已发生的行为,比如小明向小红借了 1000 元,但没打借条,或者打了借条但没有签名,就会造成小红的资金损失。接下来我们一步步来看看 HTTPS 是如何实现以满足以上四大安全通信原则的。
既然 HTTP 是明文传输的,那我们给报文加密不就行了,既然要加密,我们肯定需要通信双方协商好密钥吧。一种是通信双方使用同一把密钥,即对称加密的方式来给报文进行加解密。
对称加密:通信双方使用同一把密钥进行加、解密
对称加密具有加解密速度快,性能高的特点,也是 HTTPS 最终采用的加密形式。
但是,这里有一个关键问题:对称加密的通信双方要使用同一把密钥,这个密钥是如何协商出来的?如果通过报文的方式直接传输密钥,之后的通信其实还是在裸奔,因为这个密钥会被中间人截获甚至替换掉,这样中间人就可以用截获的密钥解密报文,甚至替换掉密钥以达到篡改报文的目的。
有人说对这个密钥加密不就完了,但对方如果要解密这个密钥还是要传加密密钥给对方,依然还是会被中间人截获的,这么看来:直接传输密钥无论怎样都无法摆脱俄罗斯套娃的难题,是不可行的。
直接传输密钥,无论从哪一端传都是不行了,这里我们试一下另一种加密方式:非对称加密。
非对称加密即加解密双方使用不同的密钥,一把作为公钥,可以公开的,一把作为私钥,不能公开,公钥加密的密文只有私钥可以解密,私钥加密的内容,也只有公钥可以解密。
注意:
私钥加密其实这个说法其实并不严谨,准确的说私钥加密应该叫私钥签名。因为私密加密的信息公钥是可以解密的,而公钥是公开的,任何人都可以拿到,用公钥解密叫做验签。
这样的话,对于 Server 来说,保管好私钥,发布公钥给其他 Client, 其他 Client 只要把对称加密的密钥加密传给 Server 即可。如此一来由于公钥加密只有私钥能解密,而私钥只有 Server 有,所以能保证 Client 向 Server 传输是安全的,Server 解密后即可拿到对称加密密钥,这样交换了密钥之后就可以用对称加密密钥通信了。
但是问题又来了, Server 怎么把公钥安全地传输给 Client 呢?如果直接传公钥,也会存在被中间人调包的风险。
如何解决公钥传输问题呢?
从现实生活中的场景找答案:员工入职时,企业一般会要求提供学历证明,显然不是什么阿猫阿狗的本本都可称为学历,这个学历必须由第三方权威机构(Certificate Authority,简称 CA)即教育部颁发。同理,Server 也可以向 CA 申请证书,在证书中附上公钥,然后将证书传给 Client,证书由站点管理者向 CA 申请,申请的时候会提交 DNS 主机名等信息,CA 会根据这些信息生成证书。
这样当 Client 拿到证书后,就可以获得证书上的公钥,再用此公钥加密对称加密密钥传给 Server 即可。看起来确实很完美,不过在这里要考虑两个问题:
问题一: 如何验证证书的真实性?如何防止证书被篡改?
想象一下上文中我们提到的学历,企业如何认定你提供的学历证书是真是假呢?答案是用学历编号,企业拿到证书后用学历编号在学信网上一查就知道证书真伪了,学历编号其实就是我们常说的数字签名,可以防止证书造假。
回到 HTTPS 上,证书的数字签名该如何产生的呢?一图胜千言:
步骤如下 :
1、首先使用一些摘要算法(如 MD5)将证书明文(如证书序列号,DNS 主机名等)生成摘要,然后再用第三方权威机构的私钥对生成的摘要进行加密(签名)。
消息摘要是把任意长度的输入揉和而产生长度固定的伪随机输入的算法,无论输入的消息有多长,计算出来的消息摘要的长度总是固定的。一般来说,只要内容不同,产生的摘要必然不同(相同的概率可以认为接近于 0),所以可以验证内容是否被篡改了。
为什么要先生成摘要再加密呢,不能直接加密?
因为使用非对称加密是非常耗时的。如果把整个证书内容都加密生成签名的话,客户端验签也需要把签名解密,证书明文较长,客户端验签就需要很长的时间,而用摘要的话,会把内容很长的明文压缩成小得多的定长字符串,客户端验签的话就会快得多。
2、客户端拿到证书后,首先,使用第三方权威机构的公钥对签名进行解密(验签),得到验签的结果(摘要)。然后,用同样的摘要算法对证书明文计算摘要。两者一笔对就可以发现报文是否被篡改了。
为什么要用第三方权威机构(Certificate Authority,简称 CA)私钥对摘要加密呢?
因为摘要算法是公开的,中间人可以替换掉证书明文,再根据证书上的摘要算法计算出摘要后把证书上的摘要也给替换掉!这样 Client 拿到证书后计算摘要发现一样,误以为此证书是合法就中招了。所以,必须要用 CA 的私钥给摘要进行加密生成签名,这样的话 Client 得用 CA 的公钥来给签名解密,拿到的才是未经篡改合法的摘要(私钥签名,公钥才能解密)。
Server 将证书传给 Client 后,Client 的验签过程如下:
这样的话,由于只有 CA 的公钥才能解密签名,如果客户端收到一个假的证书,使用 CA 的公钥是无法解密的,如果客户端收到了真的证书,但证书上的内容被篡改了,摘要比对不成功的话,客户端也会认定此证书非法。
细心的你一定发现了问题,CA 公钥如何安全地传输到 Client ?
如果还是从 Server 传输到 Client,依然无法解决公钥被调包的风险。实际上此公钥是存在于 CA 证书上,而此证书(也称 Root CA 证书)被操作系统信任,内置在操作系统上的,无需传输,如果用的是 Mac 的同学,可以打开 keychains 查看一下,可以看到很多内置的被信任的证书。
Server 传输 CA 颁发的证书,客户收到证书后使用内置 CA 证书中的公钥来解密签名,验签即可,这样的话就解决了公钥传输过程中被调包的风险。
问题二: 如何防止证书被调包?
实际上任何站点都可以向第三方权威机构申请证书,中间人也不例外。
正常站点和中间人都可以向 CA 申请证书,获得认证的证书由于都是 CA 颁发的,所以都是合法的。那么此时中间人是否可以在传输过程中将正常站点发给 Client 的证书替换成自己的证书呢?
答案是:不行。因为客户端除了通过验签的方式验证证书是否合法之外,还需要验证证书上的域名与自己的请求域名是否一致,中间人中途虽然可以替换自己向 CA 申请的合法证书,但此证书中的域名与 Client 请求的域名不一致,Client 会认定为不通过!
但是,上面的证书调包给了我们一种思路,什么思路?大家想想, HTTPS 既然是加密的, charles 这些中间人为啥能抓到明文的包呢?其实就是用了证书调包这一手法,想想看,在用 charles 抓 HTTPS 的包之前我们先要做什么,当然是安装 charles 的证书。
这个证书里有 charles 的公钥,这样的话 charles 就可以将 Server 传给 Client 的证书调包成自己的证书,Client 拿到后就可以用自己安装的 charles 证书来验签等,验证通过之后就会用 charles 证书中的公钥来加密对称密钥了。整个流程如下:
由此可知,charles 这些中间人能抓取 HTTPS 包的前提是:Client 信任它们的 CA 证书,然后就可以通过替换证书的方式进行瞒天过海,所以我们千万不要随便信任第三方的证书,避免安全风险。
尽管HTTPS并非绝对安全,掌握根证书的机构、掌握加密算法的组织同样可以进行中间人形式的攻击,但HTTPS仍是现行架构下最安全的解决方案,主要有以下几个好处:
(1)使用HTTPS协议可认证用户和服务器,确保数据发送到正确的客户机和服务器;
(2) HTTPS协议是由SSL + HTTP协议构建的可进行加密传输、身份认证的网络协议,要比HTTP协议安全,可防止数据在传输过程中不被窃取、改变,确保数据的完整性。
(3) HTTPS是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本。
(4)谷歌曾在2014年8月份调整搜索引擎算法,并称“比起同等HTTP网站,采用HTTPS加密的网站在搜索结果中的排名将会更高”。
虽然说 HTTPS 有很大的优势,但其相对来说,还是存在不足之处的:
(1)HTTPS协议握手阶段比较费时,会使页面的加载时间延长近50%,增加10%到20%的耗电;
(2)HTTPS连接缓存不如HTTP高效,会增加数据开销和功耗,甚至已有的安全措施也会因此而受到影响;
(3)SSL证书需要钱,功能越强大的证书费用越高,个人网站、小网站没有必要一般不会用。
(4)SSL证书通常需要绑定IP,不能在同一IP上绑定多个域名,IPv4资源不可能支撑这个消耗。
(5)HTTPS协议的加密范围也比较有限,在黑客攻击、拒绝服务攻击、服务器劫持等方面几乎起不到什么作用。最关键的,SSL证书的信用链体系并不安全,特别是在某些国家可以控制 CA 根证书的情况下,中间人攻击一样可行。
1、https
协议需要到CA
申请证书,一般免费证书较少,因而需要一定费用。
2、http
是超文本传输协议,信息是明文传输,https
则是具有安全性的ssl
加密传输协议。
3、http
和https
使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443
。
4、http
的连接很简单,是无状态的;HTTPS
协议是由SSL + HTTP
协议构建的可进行加密传输、身份认证的网络协议,比http
协议安全。
HTTPS协议用到的安全技术:对称加密算法、非对称加密算法、证书-签名机制。
★ 对称加密算法:加密传输数据。
★ 非对称加密算法:加密对称加密算法的秘钥。
★ 证书-签名机制:Client 通过 Server 返回的证书-签名确认其合法身份,并获取非对称加密算法的公钥。