https

2016/08/27

http为什么不安全?

        http协议属于明文传输协议,交互过程以及数据传输都没有进行加密,通信双方也没有进行任何认证,通信过程非常容易遭遇劫持、监听、篡改,严重情况下,会造成恶意的流量劫持等问题,甚至造成个人隐私泄露(比如银行卡卡号和密码泄露)等严重的安全问题。

        可以把http通信比喻成寄送信件一样,A给B寄信,信件在寄送过程中,会经过很多的邮递员之手,他们可以拆开信读取里面的内容(因为http是明文传输的)。A的信件里面的任何内容(包括各类账号和密码)都会被轻易窃取。除此之外,邮递员们还可以伪造或者修改信件的内容,导致B接收到的信件内容是假的。

        比如常见的,在http通信过程中,“中间人”将广告链接嵌入到服务器发给用户的http报文里,导致用户界面出现很多不良链接;或者是修改用户的请求头URL,导致用户的请求被劫持到另外一个网站,用户的请求永远到不了真正的服务器。这些都会导致用户得不到正确的服务,甚至是损失惨重。

https如何保证安全?

        要解决http带来的问题,就要引入加密以及身份验证机制。

        如果Server(以后简称 服务器)给Client(以后简称客户端)的消息是密文的,只有服务器和客户端才能读懂,就可以保证数据的保密性。同时,在交换数据之前,验证一下对方的合法身份,就可以保证通信双方的安全。那么,问题来了,服务器把数据加密后,客户端如何读懂这些数据呢?这时服务器必须要把加密的密钥(对称密钥,后面会详细说明)告诉客户端,客户端才能利用对称密钥解开密文的内容。但是,服务器如果将这个对称密钥以明文的方式给客户端,还是会被中间人截获,中间人也会知道对称密钥,依然无法保证通信的保密性。但是,如果服务器以密文的方式将对称密钥发给客户端,客户端又如何解开这个密文,得到其中的对称密钥呢?

        说到这里,大家是不是有点儿糊涂了?一会儿密钥,一会儿对称密钥,都有点儿被搞晕的节奏。在这里,提前给大家普及一下,这里的密钥,指的是非对称加解密的密钥,是用于TLS握手阶段的;对称密钥,指的是对称加解密的密钥,是用于后续传输数据加解密的。下面将详细说明。

        这时,我们引入了非对称加解密的概念。在非对称加解密算法里,公钥加密的数据,有且只有唯一的私钥才能够解密,所以服务器只要把公钥发给客户端,客户端就可以用这个公钥来加密进行数据传输的对称密钥。客户端利用公钥将对称密钥发给服务器时,即使中间人截取了信息,也无法解密,因为私钥只部署在服务器,其他任何人都没有私钥,因此,只有服务器才能够解密。服务器拿到客户端的信息并用私钥解密之后,就可以拿到加解密数据用的对称密钥,通过这个对称密钥来进行后续通信的数据加解密。除此之外,非对称加密可以很好的管理对称密钥,保证每次数据加密的对称密钥都是不相同的,这样子的话,即使客户端病毒拉取到通信缓存信息,也无法窃取正常通信内容。

        上述通信过程,可以画成以下交互图:

trans

        但是这样似乎还不够,如果通信过程中,在三次握手或者客户端发起HTTP请求过程中,客户端的请求被中间人劫持,那么中间人就可以伪装成“假冒客户端”和服务器通信;中间人又可以伪装成“假冒服务器”和客户端通信。接下来,我们详细阐述中间人获取对称密钥的过程:

        中间人在收到服务器发送给客户端的公钥(这里是“正确的公钥”)后,并没有发给客户端,而是中间人将自己的公钥(这里中间人也会有一对公钥和私钥,这里称呼为“伪造公钥”)发给客户端。之后,客户端把对称密钥用这个“伪造公钥”加密后,发送过程中经过了中间人,中间人就可以用自己的私钥解密数据并拿到对称密钥,此时中间人再把对称密钥用“正确的公钥”加密发回给服务器。此时,客户端、中间人、服务器都拥有了一样的对称密钥,后续客户端和服务器的所有加密数据,中间人都可以通过对称密钥解密出来。

        中间人获取对称密钥的过程如下:

attack

        为了解决此问题,我们引入了数字证书的概念。服务器首先生成公私钥,将公钥提供给相关机构(CA),CA将公钥放入数字证书并将数字证书颁布给服务器,此时服务器就不是简单的把公钥给客户端,而是给客户端一个数字证书,数字证书中加入了一些数字签名的机制,保证了数字证书一定是服务器给客户端的。中间人发送的伪造证书,不能够获得CA的认证,此时,客户端和服务器就知道通信被劫持了。加入了CA数字签名认证的SSL会话过程如下所示:

ca

        所以综合以上三点: 非对称加密算法(公钥和私钥)交换对称密钥 + 数字证书验证身份(验证公钥是否是伪造的) + 利用对称密钥加解密后续传输的数据 = 安全

safe

https协议简介

        为什么是简单地介绍https协议呢?因为https涉及的东西实在太多了,尤其是其中的加解密算法,十分复杂,作者本身对这些算法也研究不完,只是懂其中的一些皮毛而已。这部分仅仅是简单介绍一些关于https的最基本原理,为后面分析https的建立过程以及https优化等内容打下理论基础。

对称加密算法

        对称加密是指:加密和解密使用相同密钥的算法。它要求发送方和接收方在安全通信之前,商定一个对称密钥。对称算法的安全性完全依赖于密钥,密钥泄漏就意味着任何人都可以对他们发送或接收的消息解密,所以密钥的保密性对通信至关重要。

对称加密又分为两种模式:流加密和分组加密。

        流加密是将消息作为字节流对待,并且使用数学函数分别作用在每一个字节位上。使用流加密时,每加密一次,相同的明文位会转换成不同的密文位。流加密使用了密钥流生成器,它生成的字节流与明文字节流进行异或,从而生成密文。

        分组加密是将消息划分为若干个分组,这些分组随后会通过数学函数进行处理,每次一个分组。假设使用64位的分组密码,此时如果消息长度为640位,就会被划分成10个64位的分组(如果最后一个分组长度不到64,则用0补齐之后加到64位),每个分组都用一系列数学公式进行处理,最后得到10个加密文本分组。然后,将这条密文消息发送给对端。对端必须拥有相同的分组密码,以相反的顺序对10个密文分组使用前面的算法解密,最终得到明文消息。比较常用的分组加密算法有DES、3DES、AES。其中DES是比较老的加密算法,现在已经被证明不安全。而3DES是一个过渡的加密算法,相当于在DES基础上进行三重运算来提高安全性,但其本质上还是和DES算法一致。而AES是DES算法的替代算法,是现在最安全的对称加密算法之一。

对称加密算法的优缺点:

优点: 计算量小、加密速度快、加密效率高。

缺点:(1)交易双方都使用同样密钥,安全性得不到保证;

             (2)每次使用对称加密算法时,都需要使用其他人不知道的惟一密钥,这会使得发收信息双方所拥有的钥匙数量呈几何级数增长,密钥管理成为负担

非对称加密算法

             在非对称密钥交换算法出现以前,对称加密的最主要缺陷就是不知道如何在通信双方之间传输对称密钥,而又不让中间人窃取。非对称密钥交换算法诞生之后,专门针对对称密钥传输做加解密,使得对称密钥的交互传输变得非常安全了。

             非对称密钥交换算法本身非常复杂,密钥交换过程涉及到随机数生成,模指数运算,空白补齐,加密,签名等等一系列极其复杂的过程,作者本人也没有研究完全透彻。

             常见的密钥交换算法有RSA,ECDHE,DH,DHE等算法。涉及到比较复杂的数学问题。其中,最经典也是最常用的是RSA算法。

             RSA:诞生于1977年,经过了长时间的破解测试,算法安全性很高,最重要的是,算法实现非常简单。缺点就是需要比较大的质数(目前常用的是2048位)来保证安全强度,极其消耗CPU运算资源。RSA是目前唯一一个既能用于密钥交换又能用于证书签名的算法,RSA 是最经典,同时也是最常用的是非对称加解密算法

非对称加密相比对称加密更加安全,但也存在两个致命的缺点:

             (1) CPU计算资源消耗非常大。一次完全TLS握手,密钥交换时的非对称解密计算量占整个握手过程的90%以上。而对称加密的计算量只相当于非对称加密的0.1%。如果后续的应用层数据传输过程也使用非对称加解密,那么CPU性能开销太庞大,服务器是根本无法承受的。赛门特克给出的实验数据显示,加解密同等数量的文件,非对称算法消耗的CPU资源是对称算法的1000倍以上。

             (2) 非对称加密算法对加密内容的长度有限制,不能超过公钥长度。比如现在常用的公钥长度是2048位,意味着待加密内容不能超过256个字节。

             所以非对称加解密(极端消耗CPU资源)目前只能用来作对称密钥交换或者CA签名,不适合用来做应用层内容传输的加解密。

身份认证

             https协议中身份认证的部分是由CA数字证书完成的,证书由公钥、证书主体、数字签名等内容组成。在客户端发起SSL请求后,服务端会将数字证书发给客户端,客户端会对证书进行验证(验证这张证书是否是伪造的?也就是公钥是否是伪造的),如果证书不是伪造的,客户端就获取用于对称密钥交换的非对称密钥(获取公钥)。

数字证书有三个作用

             1、身份授权。确保浏览器访问的网站是经过CA验证的可信任的网站。

             2、分发公钥。每个数字证书都包含了注册者生成的公钥(验证确保是合法的,非伪造的公钥)。在SSL握手时会通过certificate消息传输给客户端。

             3、验证证书合法性。客户端接收到数字证书后,会对证书合法性进行验证。只有验证通过后的证书,才能够进行后续通信过程。

申请一个受信任的CA数字证书通常有如下流程:

             (1)公司(实体)的服务器生成公钥和私钥,以及CA数字证书请求。

             (2)RA(证书注册及审核机构)检查实体的合法性(在注册系统里面是否注册过的正规公司)。

             (3)CA(证书签发机构)签发证书,发送给申请者实体。

             (4)证书更新到repository(负责数字证书及CRL内容存储和分发),实体终端后续从repository更新证书,查询证书状态等。

数字证书验证

             申请者拿到CA的证书并部署在网站服务器端,那浏览器发起握手并接收到证书后,如何确认这个证书就是CA签发的呢?怎样避免第三方伪造这个证书?答案就是数字签名(digital signature)。数字签名是证书的防伪标签,目前使用最广泛的SHA-RSA(SHA用于哈希算法,RSA用于非对称加密算法)。数字签名的制作和验证过程如下:

             1、数字签名的签发。首先是使用哈希函数对待签名内容进行安全哈希,生成消息摘要,然后使用CA自己的私钥对消息摘要进行加密。

             2、数字签名的校验。使用CA的公钥解密签名,然后使用相同的签名函数对签名证书内容进行签名,并和服务端数字签名里的签名内容进行比较,如果相同就认为校验成功。

sig

需要注意的是:

             (1) 数字签名签发和校验使用的非对称密钥是CA自己的公钥和私钥,跟证书申请者(提交证书申请的公司实体)提交的公钥没有任何关系。

             (2) 数字签名的签发过程跟公钥加密的过程刚好相反,即是用私钥加密,公钥解密。(一对公钥和私钥,公钥加密的内容只有私钥能够解密;反过来,私钥加密的内容,也就有公钥才能够解密)

             (3) 现在大的CA都会有证书链,证书链的好处:首先是安全,保持CA的私钥离线使用。第二个好处是方便部署和撤销。这里为啥要撤销呢?因为,如果CA数字证书出现问题(被篡改或者污染),只需要撤销相应级别的证书,根证书依然是安全的。

             (4) 根CA证书都是自签名,即用自己的公钥和私钥完成了签名的制作和验证。而证书链上的证书签名都是使用上一级证书的非对称密钥进行签名和验证的。

             (5) 怎样获取根CA和多级CA的密钥对?还有,既然是自签名和自认证,那么它们是否安全可信?这里的答案是:当然可信,因为这些厂商跟浏览器和操作系统都有合作,它们的根公钥都默认装到了浏览器或者操作系统环境里。

数据完整性验证

             数据传输过程中的完整性使用MAC算法来保证。为了避免网络中传输的数据被非法篡改,或者数据比特被污染,SSL利用基于MD5或SHA的MAC算法来保证消息的完整性(由于MD5在实际应用中存在冲突的可能性比较大,所以尽量别采用MD5来验证内容一致性)。MAC算法是在密钥参与下的数据摘要算法,能将密钥和任意长度的数据转换为固定长度的数据。发送者在密钥的作用下,利用MAC算法计算出消息的MAC值,并将其添加在需要发送的消息之后,并发送给接收者。接收者利用同样的密钥和MAC算法计算出消息的MAC值,并与接收到的MAC值比较。如果二者相同,则报文没有改变;否则,报文在传输过程中被修改或者污染,接收者将丢弃该报文。 SHA也不能使用SHA0和SHA1,山东大学的王小云教授(很牛的一个女教授,大家有兴趣可以上网搜索一下她的事迹)在2005年就宣布破解了SHA-1完整版算法,并获得了业内专家的认可。微软和google都已经宣布16年及17年之后不再支持sha1签名证书。

Post Directory