真正“搞”懂HTTPS协议16之安全的实现

  上一篇噢,我们搞明白了什么是安全的通信,这个很重要,特别重要,敲黑板!!

  然后,我们还学了HTTPS到底是什么,以及HTTPS真正的核心SSL/TLS是什么。最后我们还聊了聊TLS的实现,也就是OpenSSL。

  那么这一篇,就会稍微长一点了,很重要!我们来聊一聊,安全的四大特性是如何被TLS实现的。

一、机密性的实现

  说起机密性,不知道大家第一时间是不是跟我想的一样。加密呗。一点毛病没有~就是加密。加密说白了就是把谁都能看的懂的内容,转换成只有拥有钥匙的人才看的懂的内容。这里的“钥匙”就叫做“密钥”(key),加密前的消息叫“明文”(plain text/clear text),加密后的乱码叫“密文”(cipher text),使用密钥还原明文的过程叫“解密”(decrypt),是加密的反操作,加密解密的操作过程就是“加密算法”。

  所有的加密算法都是公开的,任何人都可以去分析研究,而算法使用的“密钥”则必须保密。

  那么,这个关键的“密钥”又是什么呢?

  由于 HTTPS、TLS 都运行在计算机上,所以“密钥”就是一长串的数字,但约定俗成的度量单位是“位”(bit),而不是“字节”(byte)。比如,说密钥长度是 128,就是 16 字节的二进制串,密钥长度 1024,就是 128 字节的二进制串。

  按照密钥的使用方式,加密可以分为两大类:对称加密非对称加密

一)对称加密

  对称加密很好理解,就是指加密和解密都是使用的同一个密钥,是”对称“的。只要保证了密钥的安全,那整个通信过程就可以说具备了机密性。

  举个例子,你想要登录某个网站,只要事先与它约定好使用一个对称密钥,通信过程中全是用密钥加密后的密文,只有你和网站才能解密,黑客即使能够窃听,看到的也是乱码,因为没有密钥无法解出明文,所以就实现了机密性。

  

   这图片我复制过来的~懒得画了,哈哈哈。

  TLS 里有非常多的对称加密算法可供选择,比如 RC4、DES、3DES、AES、ChaCha20 等,但前三种算法都被认为是不安全的,通常都禁止使用,目前常用的只有 AES 和 ChaCha20

  AES 的意思是“高级加密标准”(Advanced Encryption Standard),密钥长度可以是 128、192 或 256。它是 DES 算法的替代者,安全强度很高,性能也很好,而且有的硬件还会做特殊优化,所以非常流行,是应用最广泛的对称加密算法。

  ChaCha20 是 Google 设计的另一种加密算法,密钥长度固定为 256 位,纯软件运行性能要超过 AES,曾经在移动客户端上比较流行,但 ARMv8 之后也加入了 AES 硬件优化,所以现在不再具有明显的优势,但仍然算得上是一个不错的算法。

  所以,总结下来,我们只要知道TLS最常用的对称加密算法就是AES,其它的加密算法要么不安全,要么就跟AES差不多。

加密分组模式

  对称加密还有个”分组模式“的概念,它可以让算法用固定长度的密钥加密任意长度的明文。

  最早有 ECB、CBC、CFB、OFB 等几种分组模式,但都陆续被发现有安全漏洞,所以现在基本都不怎么用了。最新的分组模式被称为 AEAD(Authenticated Encryption with Associated Data),在加密的同时增加了认证的功能,常用的是 GCM、CCM 和 Poly1305

  把上面这些组合起来,就可以得到 TLS 密码套件中定义的对称加密算法。

  比如,AES128-GCM,意思是密钥长度为 128 位的 AES 算法,使用的分组模式是 GCM;ChaCha20-Poly1305 的意思是 ChaCha20 算法,使用的分组模式是 Poly1305。

二)非对称加密

  对称加密看上去好像还不错,但是其中有一个很大的问题,就是通信的双方如何安全的把密钥传递给对方,术语叫做”密钥交换“。

  因为再对称加密算法中,密钥成了密文的关键,只要持有密钥,就能解密密文获得明文数据。虽然黑客无法直接解密传输过程中的密文,但是可以拦截捕获传输过程中传递的密钥,那他就可以在之后随意解密收发的数据,通信过程也就没有机密性可言了。

  怎么解决这个问题呢,嗯……那就再把密钥也加密一下,但是传输加”密密钥的密钥“又出现了同样的问题,得~~这样不就死循环了?所以,只用对称加密算法,是绝对无法解决密钥交换的问题的。

  所以,就出现了非对称加密(也叫公钥加密算法)。

  它有两个密钥,一个叫“公钥”(public key),一个叫“私钥”(private key)。两个密钥是不同的,“不对称”,公钥可以公开给任何人使用,而私钥必须严格保密。

  公钥和私钥有个特别的“单向”性,虽然都可以用来加密解密,但公钥加密后只能用私钥解密,反过来,私钥加密后也只能用公钥解密。这个逻辑很重要,我们后面还会接触到。要记住噢~

  非对称加密可以解决“密钥交换”的问题。网站秘密保管私钥,在网上任意分发公钥,你想要登录网站只要用公钥加密就行了,密文只能由私钥持有者才能解密。而黑客因为没有私钥,所以就无法破解密文。

  非对称加密算法的设计要比对称算法难得多,在 TLS 里只有很少的几种,比如 DH、DSA、RSA、ECC 等。

  RSA 可能是其中最著名的一个,几乎可以说是非对称加密的代名词,它的安全性基于“整数分解”的数学难题,使用两个超大素数的乘积作为生成密钥的材料,想要从公钥推算出私钥是非常困难的。

  10 年前 RSA 密钥的推荐长度是 1024,但随着计算机运算能力的提高,现在 1024 已经不安全,普遍认为至少要 2048 位。

  ECC(Elliptic Curve Cryptography)是非对称加密里的“后起之秀”,它基于“椭圆曲线离散对数”的数学难题,使用特定的曲线方程和基点生成公钥和私钥,子算法 ECDHE 用于密钥交换,ECDSA 用于数字签名。

  比起 RSA,ECC 在安全强度和性能上都有明显的优势。160 位的 ECC 相当于 1024 位的 RSA,而 224 位的 ECC 则相当于 2048 位的 RSA。因为密钥短,所以相应的计算量、消耗的内存和带宽也就少,加密解密的性能就上去了,对于现在的移动互联网非常有吸引力。

  我们要记住RSA、ECC这两个非对称加密算法。很重要。

三)混合加密

  那~我们直接用非对称加密不就完美了么?也不行,虽然非对称加密没有”密钥交换“的问题,但因为它们都是基于复杂的数学难题,运算速度很慢,即使是 ECC 也要比 AES 差上好几个数量级。如果仅用非对称加密,虽然保证了安全,但通信速度有如乌龟、蜗牛,实用性就变成了零。

  那怎么办呢?开动脑筋想一想?

  我们可以把对称加密和非对称加密结合起来,两者互相取长补短,即能高效地加密解密,又能安全地密钥交换。

  这就是现在 TLS 里使用的混合加密方式

  在通信刚开始的时候使用非对称算法,比如 RSA、ECDHE,首先解决密钥交换的问题。

  然后用随机数产生对称算法使用的“会话密钥”(session key),再用公钥加密。因为会话密钥很短,通常只有 16 字节或 32 字节,所以慢一点也无所谓。对方拿到密文后用私钥解密,取出会话密钥。这样,双方就实现了对称密钥的安全交换,后续就不再使用非对称加密,全都使用对称加密。

  这样混合加密就解决了对称加密算法的密钥交换问题,而且安全和性能兼顾,完美地实现了机密性。

  到目前为止还没完,我们还需要解决其它三个特性的问题才可以。万里长征的第一步要走稳。

二、实现完整性

  上一小节,我们通过学习对称加密和非对称加密的混合加密方式,了解了TLS是如何实现通信的机密性的,但是只有机密性还远远不够。

  虽然黑客拿不到会话密钥,无法破解密文,但是可以通过窃听足够多的密文,再尝试修改、重组后发给网站。因为没有完整性保证,服务器只能“照单全收”,然后他就可以通过服务器的响应获取进一步的线索,最终就会破解出明文。

  另外,黑客也可以伪造身份发布公钥。如果你拿到了假的公钥,混合加密就完全失效了。你以为自己是在和“某宝”通信,实际上网线的另一端却是黑客,银行卡号、密码等敏感信息就在“安全”的通信过程中被窃取了。

  那么我们接下来要学习的就是,如何保证会话的完整性,让黑客修改后的报文被服务器拒绝。

一)摘要算法

  实现完整性的手段主要是摘要算法(Digest Algorithm),也就是常说的散列函数、哈希函数(Hash Function)。

  你可以把摘要算法理解成一种单向的压缩算法,它能够把任意长度的数据压缩成固定长度、且独一无二的”摘要“字符串,就好像是给数据加上了一个”指纹“。摘要算法只有算法,没有密钥,也无法解密,所以也无法逆推出原文。

  摘要算法实际上是把数据从一个大空间,映射到了一个小空间,所以就存在冲突(也叫做碰撞)的可能性,就如同现实中的指纹一样,可能会有两份不同的原文对应相同的摘要。好的摘要算法必须能够“抵抗冲突”,让这种可能性尽量地小。

  你一定在日常工作中听过、或者用过 MD5(Message-Digest 5)、SHA-1(Secure Hash Algorithm 1),它们就是最常用的两个摘要算法,能够生成 16 字节和 20 字节长度的数字摘要。但这两个算法的安全强度比较低,不够安全,在 TLS 里已经被禁止使用了。目前 TLS 推荐使用的是 SHA-1 的后继者:SHA-2。

  SHA-2 实际上是一系列摘要算法的统称,总共有 6 种,常用的有 SHA224、SHA256、SHA384,分别能够生成 28 字节、32 字节、48 字节的摘要。

二)完整性的实现

  摘要算法保证了”数字摘要“和原文是等价的。所以,我们只需要在原文后附上它的摘要,就能够保证数据的完整性。

  服务器通过计算源数据的摘要,然后和传过来的摘要比对一下,就可以知道是否是完整的未被修改的数据。如果黑客在中间哪怕改动了一个标点符号,摘要也会完全不同,网站计算比对就会发现消息被窜改,是不可信的。

  不过摘要算法没有机密性,如果明文传输,那么黑客可以修改消息后把摘要也一起改了,网站还是鉴别不出完整性。

  所以,真正的完整性必须要建立在机密性之上,在混合加密系统里用会话密钥加密消息和摘要,这样黑客无法得知明文,也就没有办法动手脚了。这有个术语,叫哈希消息认证码(HMAC)。

三、身份认证与不可否认

  加密算法结合摘要算法,可以说数据在通信”过程“中是比较安全的了。但是只是过程中的安全,还不行,我们还要关注通信的两个端点。

  黑客可以伪装成网站来窃取信息。但是反过来,黑客还可以伪装成”你“,向网站发送支付、转账信息,网站没有办法确认你是谁,钱就这么被偷走了。

  那,在现实生活中,我们通常通过签名、盖章、加身份证号,来在合同上确认你是谁,确认这份文件确实是你签署的,可以负法律责任了。

  那,我们回忆一下,我再限定一下、缩小一下范围,我们在第一小节学习的内容中,有啥是可以确认你是谁的呢?

  没错,这个东西就是非对称加密里的“私钥”,使用私钥再加上摘要算法,就能够实现“数字签名”,同时实现“身份认证”和“不可否认”。

  数字签名的原理其实很简单,就是把公钥私钥的用法反过来,之前是公钥加密、私钥解密,现在是私钥加密、公钥解密。

  但是又因为非对称加密效率太低,所以私钥只加密原文的摘要,这样运算量就小的多,而且得到的数字签名也很小,方便保管和传输。

  签名和公钥一样完全公开,任何人都可以获取。但这个签名只有用私钥对应的公钥才能解开,拿到摘要后,再比对原文验证完整性,就可以像签署文件一样证明消息确实是你发的。

  刚才的这两个行为也有专用术语,叫做“签名”和“验签”。

  只要你和网站互相交换公钥,就可以用“签名”和“验签”来确认消息的真实性,因为私钥保密,黑客不能伪造签名,就能够保证通信双方的身份。

  到现在哈,其实我们就解决了所有的问题。机密性通过对称加密和非对称加密的混合加密来解决,完整性就是数字摘要,身份认证和不可否认则是通过数字签名(其实就是”反过来了“,能理解不?)来解决。

  但是~还没完~

四、信任危机

  现在看起来很美好了,但是还有个问题,就是”我“可以发布公钥,那么这个我就可能不是”我“,而是黑客怎么办?黑客可以伪造公钥,换句话说,就是我怎么确定你发布的公钥是”你“发布的,或者是服务器发布的呢?

  嗯……这样的问题就叫做”公钥的信任“问题。

  那,我给这个公钥再用私钥加密一下呢?得……那又会陷入无尽的循环中,所以,此时就必须引入外力来解决了,找一个公认得可信得第三方,让它作为”信任的起点,递归的终点“,构建起公钥的信任链。

一)数字证书和CA

  我们要引入的这个第三方,就是CA(Certificate Authority,证书认证机构),它就像网络世界里的公安局、教育部、公证中心,具有极高的可信度,由它来给各个公钥签名,用自身的信誉来保证公钥无法伪造,是可信的。

  CA 对公钥的签名认证也是有格式的,不是简单地把公钥绑定在持有者身份上就完事了,还要包含序列号、用途、颁发者、有效时间等等,把这些打成一个包再签名,完整地证明公钥关联的各种信息,形成“数字证书”(Certificate)。

  知名的 CA 全世界就那么几家,比如 DigiCert、VeriSign、Entrust、Let’s Encrypt 等,它们签发的证书分 DV、OV、EV 三种,区别在于可信程度。

  DV 是最低的,只是域名级别的可信,背后是谁不知道。EV 是最高的,经过了法律和审计的严格核查,可以证明网站拥有者的身份(在浏览器地址栏会显示出公司的名字,例如 Apple、GitHub 的网站)。

  那,信任链到头了,就到根了,那根怎么证明自己呢?

  这还是信任链的问题。小一点的 CA 可以让大 CA 签名认证,但链条的最后,也就是 Root CA,就只能自己证明自己了,这个就叫“自签名证书”(Self-Signed Certificate)或者“根证书”(Root Certificate)。你必须相信,否则整个证书信任链就走不下去了。

  有了这个证书体系,操作系统和浏览器都内置了各大 CA 的根证书,上网的时候只要服务器发过来它的证书,就可以验证证书里的签名,顺着证书链(Certificate Chain)一层层地验证,直到找到根证书,就能够确定证书是可信的,从而里面的公钥也是可信的。

二)证书体系的弱点

  聊了这么多,终于确保了信息传输的安全,但是,也不是完美的。由于根证书是自证明式的,所以如果CA出了问题,被黑客攻陷,或者失误,或者被欺骗,虽然此时发布的证书是真的,但是它所代表的网站却是假的。

  这些情况其实都实际发生过。所以,我们还需要给证书体系打上一些补丁。

  针对证书欺骗问题,开发出了CRL(证书吊销列表)和OCSP(在线证书状态协议),及时废止有问题的证书。

  对于被攻陷的情况,因为涉及的证书太多,,就只能操作系统或者浏览器从根上“下狠手”了,撤销对 CA 的信任,列入“黑名单”,这样它颁发的所有证书就都会被认为是不安全的。

五、小结

  这篇文章很重要,特别重要。大家一定要好好学习。并且这篇文章内容很多,但是总结起来其实可以概括为两句话。

  一个是,信息传输的安全需要具备四大特性,机密性、完整性、身份认证和不可否认

  一个是,安全的终点是自证明的第三方

  其它的部分,其实都是TLS针对四大特性的具体实现了。

  本系列就快结束了~~~大概还有两三篇的内容。坚持~~不一定会胜利,但是不坚持,肯定会失败。共勉吧~

  哦对,其实这篇文章是抄的~

posted @ 2023-02-14 16:50  Zaking  阅读(297)  评论(0编辑  收藏  举报