受到这篇对 HTTPS 的加密过程讲得非常通俗浅显的文章的启发,想自己找些资料宏观上再总结一下 HTTPS 的加密过程,加强对 HTTPS 的理解。
想要理解 HTTPS 加密。需要理解几个概念:
- 对称加密算法
- 非对称加密算法
- CA(Certificate Authority)
- 数字证书
- 摘要算法
现在的问题是,如何在实现 HTTP 协议的情况下,对传输的信息进行加密解密?最开始使用到的是最简单的对称加密算法。
对称加密算法
对称加密算法非常简单,只要加密方和解密方都拥有同一密钥(可为128,192,256 bit 大小的密钥,密钥越长,加密解密时间越长,解密难度也越高),即可完成加密解密过程,且假设无法强制对加密过的明文进行解密。
问题:对于需要传递加密信息的双方而言,对称加密算法用于加密解密没有什么问题,但是密钥的传输就成了另外一个问题。因为密钥也需要传输才能使双方通信,密钥明文传输出去,被人轻易截取,就能利用密钥破解加密的密文。
所以引出了下面的非对称加密算法来传输密钥。
公开密钥加密(Public-Key Cryptography)的非对称加密算法
对于使用最广泛的非对称加密算法——RSA,RSA 算法基于一个简单的数论理论:将两个大素数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。
RSA 算法得出了下面的规则:通讯两方 A, B 分别都有各自的一套公钥和私钥。同一套公钥私钥当中,公钥的加密需要私钥才能解密,私钥的加密需要公钥才能解密。
假设 A 把自己的公钥公开出去,B 得到了 A 的公钥,然后 B 用 A 的公钥加密了明文,传给 A,A 用私钥解密,即可获得明文。所以,过程中公开的信息任何第三方得到都不可以破解 A 和 B 要传递的信息。有了这个算法之后,对称加密算法所用到的密钥传输安全性就没问题了。但是因为加密解密过程时间比较长,非对称加密算法不适合应用于数据量大的信息传递,只适用于密钥的传递。(这个问题解释了对于数字签名的摘要算法的必要性)
问题:虽然 RSA 算法也没有什么问题,但是却有人想出更绝的方法破解加解密的过程。这个方法就是中间人攻击。
在用非对称加密算法传递密钥的过程中,因为公钥都是公开的,并没有任何东西可以认证这个公钥是 A 的还是 B 的。现在出现了中间人 M,M 采取某种手段在 A 和 B 的通讯过程成为中间人。在 B 想要得到 A 的公钥的时候,M 向 B 谎称自己的这个公钥是 A 的公钥,B 拿到用 M 的公钥加密信息后,传出 M 手中,然后 M 拿加密过的信息,然后用自己的私钥把这个信息解密,得到明文。既然已经知道了明文,还是用 A 的公钥加密这个信息,继续给 A,这样 A 还是以为这个信息是安全的,继续用私钥解开。而在这个过程中,M 既获得了信息,又没有让 A,B 双方知道。至于这个 M 是怎么欺骗 A,B 的,又是另外一个安全的问题。总之,假如 M 只要让 B 相信这个公钥是 A 的,就可以作中间人攻击。
假如上面的 A 是服务器,B 是用户,那么中间人就很容易获取和修改 A,B 需要传输的信息。所以为了让 M 不再得逞,出现一个具有公信力的第三方——CA。
CA(Certificate Authority) 第三方认证机构
简单来说,CA 要做的就是,让 B 相信拿到的 A 的公钥真正属于 A,而不是其他中间人 M 伪造。
而在 CA 在做这件事的过程中如何才能让 B 认证这个公钥是 A 的呢?
这里需要另外一个概念:数字证书。
普通证书产生的过程就是:将个人提交的信息进行第三方具有权威性部门的认证,然后第三方权威部门确认个人信息合法无误后在自己的系统中登记,再把认证证书盖章签名给到个人手上,然后个人就可以用证书从事各类证明活动。现实世界中的做法是在个人提交的信息上盖章,例如4,6级的证书认证。假设你的成绩申请无误而合法,教育局就会将你的成绩记录,然后给你一张盖过章的证书。
数字证书同理。不过,与现实不一样,在互联网上完成一个完整的验证过程,需要兼顾到很多过程中的纰漏。
例如:
问题:证书上的章是一个不可信任的机构的,该如何认证哪些机构才是可信任机构?
现实中就是向政府部门认证哪些是登记过的可信任的部门,像4,6级证书颁发的部门——全国大学英语四六级考试委员会,是全国的教育局的下级和内部部门,是认证过的。而在互联网中,就需要顶级的最具有公信力的 CA,这个 CA 颁发的证书是最受信任的,这个就是根证书。为了不让所有鸡蛋都放在一个篮子里,其他的 CA 机构可以向上一级的 CA 机构申请成为中间 CA,获取自己的中间证书,最终个人像 A 向某一个中间 CA 申请的证书就是最终的终端普通数字证书。这个过程的签发关系就是证书链。当 B 得到 A 的数字证书之后,会在证书的信息中找到 A 申请的 CA,而这个 CA 则会根据自己中间证书找到的自己申请的 CA,就这样沿着证书链找证书,假如某个中间证书或者根证书在本机中安装有,则认证的时候会将 A 的证书设置为可被信任的。
如何识别可信任机构的这个问题就解决了。
问题:可以轻易做到用与政府同样的章在证书上盖章伪造,该如何认证这个证书不是个人盖章签名伪造的?
现实中可以在这个已经被认证的第三方机构系统中查询,像4,6级,可以到教育局的网上公开系统中查询。而在互联网中,则需要一个类似的查询验证过程——数字签名。为了对这个证书的验证,确保这个签名是来自可信任的 CA,而不是其他不可信的 CA。CA 在给 A 的数字证书中有一个数字签名。该签名是 CA 用自己的私钥对 A 的个人信息进行非对称加密得到的加密信息。当 B 得到 A 提供的数字证书,会拿到其中的数字签名和 A 的个人信息,然后用 CA 的公钥对这个数字签名进行非对称解密,得出的信息假如和 A 的数字证书中 A 的个人信息一样的话,就相信这个数字证书确实是 CA 认证过的。
如何认证这个签名是不是伪造的这个问题也解决了。但是这个问题又引出了另外一个问题:数字证书中 A 的个人信息数据比较大,而非对成加密算法的加密解密速度非常慢,使得认证过程中对个人信息的非对称加密解密非常耗占时间。所以需要用到另外一种算法来加快这个验证过程,这个算法就是摘要算法。(一直很疑惑为什么需要到摘要算法,总算找到了一个原因)
摘要算法可以将任意大小的原文消息加密并摘要成固定长度的简短密文。对于不同的原文消息,用同一种摘要算法,都可以得到不同但是固定长度的密文,而相同的原文消息,用同一种摘要算法,则可以得到相同固定长度的密文。这就解决了数字签名过程中,对数据大的个人信息文件的非对称加密解密的时间慢的问题。CA 用 A 个人信息进行摘要算法的处理,然后继续用私钥加密,作为数字证书的数字签名给到 A。B 拿到 A 提供的数字签名和 A 的个人信息,然后用 CA 的公钥解密 A 的数字签名,得到 A 个人信息的摘要。再用同一种摘要算法对 A 的个人信息进行处理,得到 A 个人信息的摘要,再与解密得到的 A 个人信息摘要对比,就可以确认改数字签名和个人信息是匹配的。
到这一步,中间人攻击已经很难可以发生了,假设 M 想要在 A 和 B 之间充当中间人,有三种手段:
- 需要从 A 服务器中直接获取域名数字证书;
- 得到 A 的域名管理,向 CA 申请证书
- 自己签发证书,然后要求 B 安装自己的证书。
对于第一第二个问题的防范,在服务器端,只要要保护好私钥和服务器和域名的安全,就不会出现大问题。
对于第三个问题,在客户端,有一个很好的例子:12306。12306 的证书就是中铁局自己搞的认证机构颁发的。当你浏览 12306 的时候,虽然请求是带 HTTPS,但是浏览器检查的时候发现这个中铁局的认证机构没有在证书链当中,会提示“可能会被攻击”,当然 12306 会要求你直接安装他们的证书。这就要求你自己的明察秋毫了,你是选择相信 ZF 的证书,然后可能以后 ZF 的某些网站可能会在中铁局的认证机构认证证书,然后假装是 HTTPS,并且可能会伪装窃取你的个人信息。所以在客户端,安装证书需要谨慎,不要随意安装不信任的证书。
下一篇文章应该会讲一下如何用 letsencrypt 在服务器给域名加上 HTTPS 的问题。
PS: 本博客就是用的 letsencrypt。
原文链接:www.ftandy.com/2016/03/29/…