我们都知道由于HTTP是明文的,整个传输过程完全透明,任何人都能够在链路中监听、修改、伪造请求/响应报文。所以不能满足我们的安全要求。比我如我们上网的信息会被轻易的截获,所浏览的网站真实性也无法验证。黑客可以伪装成银行、购物网站来盗取用户的密码等敏感信息。
维基百科:
由此就需要引入一种更加安全的协议,也就是HTTPS协议。常称为HTTP over TLS、HTTP over SSL或HTTP
Secure)是一种通过计算机网络进行安全通信的传输协议。HTTPS经由HTTP进行通信,但利用SSL/TLS来加密数据包。HTTPS开发的主要目的,是提供对网站服务器的身份认证,保护交换资料的隐私与完整性。这个协议由网景公司(Netscape)在1994年首次提出,随后扩展到互联网上。
怎么保障安全
安全的特性
一般来说,需要具备下面三个特性就可以认为是比较安全的
- 机密性(Secrecy/Confidentiality):指对数据的“保密”,只能由可信的人访问,对其他人是不可见的“秘密”,简单来说就是不能让不相关的人看到不该看的东西
- 完整性(Integrity,也叫一致性):指数据在传输过程中没有被篡改,不多也不少,“完完整整”地保持着原状。
- 身份认证(Authentication):指确认对方的真实身份,也就是“证明你真的是你”,保证消息只能发送给可信的人。
那HTTPS是怎么做到机密性、完整性这些安全特征的呢?如上维基百科所说。在原来的TCP / IP协议之上添加了一层SSL/TSL层。如下图:
所以HTTPS实现安全可靠的能力来自于SSL/TLS
SSL / TLS
传输层安全性协定(英语:Transport Layer Security,缩写:TLS)前身称为安全套接层(英语:Secure Sockets Layer,缩写:SSL)是一种安全协议,目的是为网际网路通信提供安全及数据完整性保障。
网景公司(Netscape)在1994年推出首版网页浏览器-网景领航员时,推出HTTPS协定,以SSL进行加密,这是SSL的起源。
更多关于SSL / TLS 的知识可查看维基百科-SSL/TLS这里就不赘述了
机密性保障
我们先看一下TLS是怎么保障数据的机密性的,机密性是信息安全的基础。
我们一般可以使用”秘钥“来对数据进行加密,加密之前的信息是明文的,大家都能看得懂,加密之后的数据会变得乱糟糟的”密文“,需要再次使用秘钥来对密文进行”解密“。而加解密的操作过程我们称之为”加密算法“
由于 HTTPS、TLS 都运行在计算机上,所以“密钥”就是一长串的数字,但约定俗成的度量单位是“位”(bit),而不是“字节”(byte)。比如,说密钥长度是 128,就是 16 字节的二进制串,密钥长度 1024,就是 128 字节的二进制串。
而按照秘钥的使用方式,又可以分为对称加密和非对称加密
对称加密
所谓的对称加密,就是加密和解密所使用的秘钥是同一个。只要保障了秘钥的安全,那整个通信过程就具备了机密性。
比如现在我要登录某个银行网站,只要我和银行事先约好使用一个秘钥,并且这个秘钥我们双方都保存好不会对外泄露。那么我们在通信过程中只要用这个秘钥对通信的数据进行加密,对方收到密文后再解密就可以了,中间即便被黑客窃听了,因为没有秘钥,黑客获取的也只是一团乱糟糟的密文。
目前比较常用的安全对称加密有: AES 和 ChaCha20
AES
AES 的意思是“高级加密标准”(Advanced Encryption Standard),密钥长度可以是 128、192 或 256。它是 DES 算法的替代者,安全强度很高,性能也很好,而且有的硬件还会做特殊优化,所以非常流行,是应用最广泛的对称加密算法。
ChaCha20
ChaCha20 是 Google 设计的另一种加密算法,密钥长度固定为 256 位,纯软件运行性能要超过 AES,曾经在移动客户端上比较流行,但 ARMv8 之后也加入了 AES 硬件优化,所以现在不再具有明显的优势,但仍然算得上是一个不错的算法。
问题
对称加密看上去好像完美地实现了机密性,但其中有一个很大的问题:如何把密钥安全地传递给对方,术语叫“密钥交换”。也就是上面那个例子中,在最开始,我和银行之间怎么把秘钥安全的传递给对方
因为在对称加密算法中只要持有密钥就可以解密。如果你和网站约定的密钥在传递途中被黑客窃取,那他就可以在之后随意解密收发的数据,通信过程也就没有机密性可言了。
非对称加密
基于对称加密的问题,就引入了另一种加密机制,即非对称加密。这个加密机制有两个密钥,一个叫“公钥”(public key),一个叫“私钥”(private key)。两个密钥是不同的,公钥可以公开给任何人使用,而私钥必须严格保密。
公钥和私钥有个特别的“单向”性,虽然都可以用来加密解密,但公钥加密后只能用私钥解密,反过来,私钥加密后也只能用公钥解密。
可以使用非对称加密来解决上面”秘钥“在最初传递的问题。比如银行秘密的保管私钥,公钥在网上发布,当我在转账时,把相应的数据信息使用公钥加密成密文,而银行的服务端接收到密文之后使用私钥解密即可。中途即便被黑客窃听了,由于黑客没有解密的私钥也就无法解密了。
非对称加密算法的设计要比对称算法难得多,在 TLS 里只有很少的几种,比如 DH、DSA、RSA、ECC 等。RSA 可能是其中最著名的一个,几乎可以说是非对称加密的代名词,它的安全性基于“整数分解”的数学难题,使用两个超大素数的乘积作为生成密钥的材料,想要从公钥推算出私钥是非常困难的。
10 年前 RSA 密钥的推荐长度是 1024,但随着计算机运算能力的提高,现在 1024 已经不安全,普遍认为至少要 2048 位。
混合加密
非对称加密都是基于复杂的数学难题,运算速度很慢,所以我们需要结合对称加密和非对称加密两种加密方式来实现数据的机密性。
即一开始使用公钥将对称加密的秘钥加密,对方接收到之后使用自己的私钥解密得到对称加密的秘钥。之后的通信数据就使用对称加密即可,这样既保障了安全也保障了性能。达到了又好又快的效果。这也是TLS里使用的加密方式
完整性保障
通过混合加密的方式,我们实现了数据的机密性,但仅有机密性是不够的,比如黑客可以窃听 / 截取我们的信息。虽然黑客没有私钥/对称加密秘钥来破解密文,但黑客可以尝试不断的修改数据,重新组合之后发送给服务器,因为服务器不知道有没有被修改过,只能来什么收什么,然后根据不同的接受数据给出相应的回应。黑客只要收集到了足够多的这种相应,可能也会最终破译出来。
所以我们需要一种机制,在机密性的基础上来保障数据的完整性。这样服务器才会知道接受到的数据是否完整,进而做出相应的响应
摘要算法
实现完整性的手段主要是摘要算法(Digest Algorithm),也就是常说的散列函数、哈希函数(Hash Function)。
我们可以把摘要算法理解为一种特殊的信息压缩算法,能达到的效果就是把任意长度的数据通过摘要算法变为固定长度、而且独一无二的字符串。就好像是生成了一个数字指纹一样。并且这个过程是单向的,即只有算法,而没有秘钥。加密之后的数据无法解密。不可能从加密之后的信息摘要逆推出原文。具有单向性的特点
除了单向性特点之外还具有一个雪崩效应,即原信息如果发生了微小的变化都会导致输出的剧烈变化。
在日常工作中比较常用的就是 MD5(Message-Digest 5)、SHA-1(Secure Hash Algorithm 1),它们就是最常用的两个摘要算法,能够生成 16 字节和 20 字节长度的数字摘要。但这两个算法的安全强度比较低,不够安全,在 TLS 里已经被禁止使用了。
目前 TLS 推荐使用的是 SHA-1 的后继者:SHA-2
实现数据的完整性
摘要算法保证了“数字摘要”和原文是完全等价的。所以,我们只要在原文后附上它的摘要,就能够保证数据的完整性。
比如我向银行发出消息,”转给小张1000块“,然后再附加一个SHA-2的摘要。银行服务器收到”转给小张1000块“消息后,也计算一下信息的摘要,然后比对两个指纹是否一样就能判断出信息是否被修改了。
如果黑客在信息中修改了任何内容,那么银行这边生产的指纹都会不一样。此时就能发现信息在传递的过程中被篡改了,是不可信的。
需要注意的是,随着信息一起传递的摘要本身是不具有机密性的,如果明文传递摘要的话,黑客可以连同摘要也一起修改了。那银行还是鉴别不出来。所以真正的完整性要建立在机密性之上。在混合加密中会用会话秘钥加密消息和摘要。这样黑客就无法得到明文,也就没办法篡改了。
这有个术语,叫哈希消息认证码(HMAC)。整个过程如下所示:
身份认证
数字签名
经过上面的混合加密和信息摘要,已近解决了通信过程中的机密性和完整性的问题。但此时还有一个漏洞。就是通信的两个端点,双方的身份问题。
就比如你以为你是在和银行通信,实际上在最开始对面就是黑客。而银行也以为网络的对面是用户,但实际上是黑客。
所以就要证明你通信的对面确实是银行,银行也需要确保在网络的另一端是用户。
现实生活中,解决身份认证的手段是签名和印章,只要在纸上写下签名或者盖个章,我们再办事的时候,往往在最后会让我们签个字确认是本人办理的,如果是公司的话,就需要公司的公章。
而我们在数字世界也有一个东西和公章/签名很像,可以证明我们身份的东西。这个东西就是私钥。只不过是反过来使用非对称加密,之前是公钥加密私钥解密,在这里是私钥加密,公钥来解密。而由于非对称加密的效率比较低,所以我们一般会对私钥先生成一个信息的摘要,这样运算量会小很多。而且得到的签名也要小很多,便于数据的保管和传输。这一过程我们称之为数字签名
签名和公钥一样完全公开,任何人都可以获取。但这个签名只有用私钥对应的公钥才能解开,拿到摘要后,再比对原文验证完整性,就可以像签署文件一样证明消息确实是你发的。
整个过程结合上面所说的验证信息完整性流程如下:
刚才的这两个行为也有专用术语,叫做“签名”和“验签”。
只要你和网站互相交换公钥,就可以用“签名”和“验签”来确认消息的真实性,因为私钥保密,黑客不能伪造签名,就能够保证通信双方的身份。
比如我发给银行一个消息,告知银行的服务器“我是用户杨健”并用自己的私钥加密,银行收到之后用我的公钥验签。确认身份没有问题,银行也用他的私钥说,我是银行,我收到之后用银行的公钥验签,也没有问题,此时我们就可以确定在网络两端的确实是我和银行。后面的通信就可以使用混合加密了。
数字证书和 CA
到这里其实还有一个问题,就是公钥信任问题,因为在互联网上谁都可以发布公钥,比如黑客也可以在公网上发布公钥,说我是xx银行。所以我们还需要判断这个公钥就真的是银行对外发布的公钥而不是黑客假冒的呢。?
这就类似在我们生活中,我们在银行办理大额贷款业务时,我们需要证明我真的是我的时候,一般会带着派出所颁发的身份证一样。那派出所在这其中担当的角色就是一个公认的,可信的第三方,让它作为信任链的起点。
而在网络世界中这个“第三方”就是我们常说的 CA(Certificate Authority,证书认证机构)。它就像网络世界里的派出所、教育部、公证中心,具有极高的可信度,由它来给各个公钥签名,用自身的信誉来保证公钥无法伪造,是可信的。
CA 对公钥的签名认证也是有格式的,不是简单地把公钥绑定在持有者身份上就完事了,还要包含序列号、用途、颁发者、有效时间等等,把这些打成一个包再签名,完整地证明公钥关联的各种信息,形成“数字证书”(Certificate)。知名的 CA 全世界就那么几家,比如 DigiCert、VeriSign、Entrust、Let’s Encrypt 等,它们签发的证书分 DV、OV、EV 三种,区别在于可信程度。
DV 是最低的,只是域名级别的可信,背后是谁不知道。EV 是最高的,经过了法律和审计的严格核查,可以证明网站拥有者的身份(在浏览器地址栏会显示出公司的名字,例如 Apple、GitHub 的网站)。
不过,CA 怎么证明自己呢?这还是信任链的问题。小一点的 CA 可以让大 CA 签名认证,但链条的最后,也就是 Root CA,就只能自己证明自己了,这个就叫“自签名证书”(Self-Signed Certificate)或者“根证书”(Root Certificate)。你必须相信,否则整个证书信任链就走不下去了。
证书体系的问题
证书体系(PKI,Public Key Infrastructure)虽然是目前整个网络世界的安全基础设施,但绝对的安全是不存在的,它也有弱点,还是关键的“信任”二字。
如果 CA 失误或者被欺骗,签发了错误的证书,虽然证书是真的,可它代表的网站却是假的。
还有一种更危险的情况,CA 被黑客攻陷,或者 CA 有恶意,因为它(即根证书)是信任的源头,整个信任链里的所有证书也就都不可信了。
参考资料
维基百科-HTTPS
维基百科-SSL/TLS
罗剑锋老师的HTTP协议