完全理解 HTTPS 如何做到传输安全
原 作 者:fi3ework
原文链接:https://github.com/fi3ework/blog/issues/17
HTTPS:是以安全为目标的 HTTP 通道,简单讲是 HTTP 的安全版,即 HTTP 下加入 SSL 层,HTTPS 的安全基础是 SSL,因此加密的详细内容就需要 SSL。
HTTPS 协议的主要作用可以分为两种:一种是建立一个信息安全通道,来保证数据传输的安全;另一种就是确认网站的真实性。
公开密钥加密(英语:Public-key cryptography),也称为非对称加密(英语:asymmetric cryptography),是 密码学[1] 的一种 算法[2],它需要两个密钥[3],一个是公开密钥,另一个是私有密钥;一个用作加密的时候,另一个则用作解密。使用其中一个密钥把明文[4] 加密后所得的密文[5],只能用相对应的另一个密钥才能解密得到原本的明文;甚至连最初用来加密的密钥也不能用作解密。由于加密和解密需要两个不同的密钥,故被称为非对称加密;不同于加密和解密都使用同一个密钥的对称加密[6]。虽然两个密钥在数学上相关,但如果知道了其中一个,并不能凭此计算出另外一个;因此其中一个可以公开,称为公钥,任意向外发布;不公开的密钥为私钥,必须由用户自行严格秘密保管,绝不通过任何途径向任何人提供,也不会透露给要通信的另一方,即使他被信任。
以上是来自维基百科的公钥私钥的定义,HTTPS 是基于非对称加密的,公钥和私钥是整个 HTTPS 的基础。简单来说,公钥是公开的(要不叫公钥),比如小 A 想给我发送加密信息就要他我的公钥,让他用我的公钥对信息进行加密,这个信息只有我的私钥能打开。所以私钥是绝对不能泄漏的,那么私钥只能用来解开公钥吗?并不是,公钥私钥都可以加密和用对方来解密,私钥用来签发数字签名,我用独一无二的私钥签发了一个数字签名,你们都有我的公钥,只有我签发的数字签名能用我的公钥解开,才能证明这个签名发自我。
知乎上有个回答特别精辟:
不要去硬记。 你只要想:既然是加密,那肯定是不希望别人知道我的消息,所以只有我才能解密,所以可得出公钥负责加密,私钥负责解密;同理,既然是签名,那肯定是不希望有人冒充我发消息,只有我才能发布这个签名,所以可得出私钥负责签名,公钥负责验证。
迪菲 - 赫尔曼密钥交换(英语:Diffie--Hellman key exchange,缩写为 D-H) 是一种 安全协议[7]。它可以让双方在完全没有对方任何预先信息的条件下通过不安全信道[8] 创建起一个 密钥[9]。这个密钥可以在后续的通讯中作为对称密钥[10] 来加密[11]通讯内容。
笔者本人并没很仔细理解这个算法的原理,但是作为前端在实际应用中只需要知道这个加密算法的作用就好了,中间就是黑箱。简单来说这个算法的作用就是:Alice 和 Bob 各自有对方的公钥(当然其他人也有),Alice 和 Bob 再产生一个随机数(不告诉别人),然后用两个人的公钥和自己手里的随机数产生两个数 A B,然后它们交换这两个数,每个人可以用自己手头的随机数和交换得来的数再次计算,两个人得到的数是一样的,就得到了一个共享密钥。
在 知乎[12] 上找到一个这个共享秘钥计算过程的描述
因此,client 和 server 可以 "离线" 计算出一份只有对方知道的秘钥。
公开密钥认证(英语:Public key certificate),又称公开密钥证书、公钥证书、数字证书(digital certificate)、数字认证、身份证书(identity certificate)、电子证书或安全证书,是用于 公开密钥基础建设[13] 的电子文件,用来证明 公开密钥[14] 拥有者的身份[15]。此文件包含了公钥信息、拥有者身份信息(主体)、以及数字证书认证机构[16](发行者)对这份文件的数字签名[17],以保证这个文件的整体内容正确无误[18]。
包含的内容有:
版本:现行通用版本是 V3
序号:用以辨识每一张证书,特别在撤消证书的时候有用
主体:拥有此证书的法人或自然人身份或机器,包括:
国家(C,Country)
州 / 省(S,State)
地域 / 城市(L,Location)
组织 / 单位(O,Organization)
通用名称(CN,Common Name):在 TLS 应用上,此字段一般是网域
发行者:以数字签名形式签署此证书的数字证书认证机构
有效期开始时间:此证书的有效开始时间,在此前该证书并未生效
有效期结束时间:此证书的有效结束时间,在此后该证书作废
公开密钥用途:指定证书上公钥的用途,例如数字签名、服务器验证、客户端验证等
公开密钥
公开密钥指纹
数字签名
数字签名算法
主体别名:例如一个网站可能会有多个网域(www.wikipedia.org, zh.wikipedia.org, zh.m.wikipedia.org 都是维基百科)、一个组织可能会有多个网站(_.wikipedia.org, _.wikibooks.org, *.wikidata.org 都是维基媒体基金会旗下的网域),不同的网域可以一并使用同一张证书,方便实现应用及管理
其中,在加密过程中最重要的是公开密钥和数字签名算法,前者用来生成 session key,后者是验算 hash 的方法。
数字证书认证机构(英语:Certificate Authority,缩写为 CA),也称为电子商务认证中心、电子商务认证授权机构,是负责发放和管理数字证书的权威机构,并作为电子商务交易中受信任的第三方,承担公钥体系中公钥的合法性检验的责任。
在 CA 给服务端颁发证书的同时会产生一个私钥和公钥。私钥由服务端自己保存,不可泄漏。公钥则是附带在证书的信息中,可以公开的。证书本身也附带一个证书电子签名,这个签名用来验证证书的完整性和真实性,可以防止证书被串改。
SSL 协议分为两部分:Handshake Protocol 和 Record Protocol。其中 Handshake Protocol 用来协商密钥,协议的大部分内容就是通信双方如何利用它来安全的协商出一份密钥。 Record Protocol 则定义了传输的格式。
相比对称加密,非对称加密的速度比较慢,所以它一般用于密钥交换,双方通过公钥算法协商出一份密钥,然后通过这个密钥对称加密来通信,充分结合这两者的优势。
首先,由客户端向服务端发起一个明文的无保护的请求,用来初始化 SSL(这里的客户端只是一个职责的代号,代表 "首先发送信息的一方",对前端来说,就是浏览器)。
messageclinet +---------------> server
message 中包含以下内容:
这个随机数是会在后面中用到的,其他的是用来标明客户端支持的特性的。
ServerHello Certificate* ServerKeyExchange* CertificateRequest* ServerHelloDoneclinet <---------------------+ server
服务端收到客户端发来的信息,返回给客户端自己的信息,message 中包括
这里要说一下数字证书与数字签名,数字证书这个东西是向第三方机构去申请的。
数字签名用来保证数字证书没有被篡改过,因为数字签名是用 CA 的私钥来加密的,如果第三方篡改了签名是无法用 CA 的公钥解密的(就伪装不下去了),数字签名也是 CA 给的。
数字签名的过程如下,使用证书中的数字签名算法计算证书的一个 HASH 值,然后 CA 用私钥给加密,然后给服务端,服务端保管好即可。
数字签名算法 CA 私钥加密数字证书 +-------------> HASH +-------------> 数字签名
最后服务器发送 Server Hello Done 报文通知客户端, 最初阶段的 SSL 握手协商部分结束,客户端应该发送信息了。
client:+---------------------------------------------------------------------+| CA 公钥解密 || 数字签名 +--------------------> 服务端的 HASH +-----+ || | || +-----> 是否相同 || 数字证书中的数字签名算法 | || 数字证书 +--------------------> 客户端计算的 HASH +-- + || |+----------------------------------------------------------------------+
客户端根据证书中的数字签名算法计算出数字证书的 HASH,再用本地的 CA 公钥(浏览器厂商会内置根证书,可以通过证书链将服务端的证书用内置的根证书认证)。解密出数字签名的 HASH,比较一致则表明这确实是未被篡改过的数字证书。到这一步,客户端已经成功拿到了服务端的证书。
Certificate* ClientKeyExchange CertificateVerify* [ChangeCipherSpec] Finishedclinet +---------------------> server
客户端的证书,如果服务端需要的话会发送(比如某些网银需要 U 盾来生成证书验证客户端的身份)。
如果服务端需要对客户端进行验证,在客户端收到服务端的 Server Hello 消息之后,首先需要向服务端发送客户端的证书,让服务端来验证客户端的合法性。
如果证书没有问题,客户端就会从服务器证书中取出服务器的公钥来加密以下信息回应服务端:
ChangeCipherSpec 是一个独立的协议,体现在数据包中就是一个字节的数据,用于告知服务端,客户端已经切换到之前协商好的加密套件(Cipher Suite)的状态,准备使用之前协商好的加密套件加密数据并传输了。它标志着从客户端之后发出的信息将使用 shared secret 来进行加密。
在 ChangecipherSpec 传输完毕之后,客户端会使用之前协商好的加密套件和 shared secret 加密一段 Finish 的数据传送给服务端,此数据是为了在正式传输应用数据之前对刚刚握手建立起来的加解密通道进行验证。
[ChangeCipherSpec] Finishedclinet <---------------------+ server
在这一步,服务端无论如何将得到 pre-master key,但是 SSL 有几种不同的交换密钥的算法,由 cipher suite 来决定,每种密钥交换算法需要不同的公钥来推倒,这里介绍两种:
不管用哪种方法,服务端和客户端现在都已经持有 pre-master key 后,使用私钥进行解密获得 pre-master key。再加上自己手上的 server_random 和 client_random,然后客户端和服务端会使用一个 PRF (Pseudo-Random Function) 算法来产生 master-secret。
master_secret = PRF(pre_master_secret, "master secret", ClientHello.random + ServerHello.random)
再由 master-secret 推导出 session-key(也称 shared-secret),这是双方后续通信用来最终加密的对称密钥。
一切准备好之后,服务端也回应客户端一个自己的用 session-key 加密的 ChangeCipherSpec,标明自己之后的信息也将使用 session-key 来加密。之后,服务端也会使用 session-key 加密一段 Finish 消息发送给客户端,以验证之前通过握手建立起来的加解密通道是否成功。
根据之前的握手信息,服务器和客户端的 Finished 报文交换完毕之后,如果客户端和服务端都能对 Finish 信息进行正常加解密且消息正确的被验证,则说明 SSL 连接就算建立完成。接下来,双方可以进行应用层的通信,使用上面产生的 session-key 对 HTTP 进行加密传输了。
在以上流程中, 应用层发送数据时会附加一种叫做 mac( Message Authentication Code) 的报文摘要。 MAC 能够查知报文是否遭到篡改, 从而保护报文的完整性。
最后放上一张图来总结整个 SSL 的过程,其中加密方式采用的是 RSA,但是整个流程是思路是一致的。
其实 HTTPS 要复杂的多,本文介绍的过程是简化了的,主要是理清如何安全获得对称公钥。
via The SSL/TLS Handshake: an Overview[20]
ssltls_handshake
放上 HTTPS 的好处与坏处,via https 是什么?使用 https 的好处与不足?[21]
正是由于 HTTPS 非常的安全,攻击者无法从中找到下手的地方,从站长的角度来说,HTTPS 的优点有以下 2 点:
虽然说 HTTPS 有很大的优势,但其相对来说,还是有些不足之处的,具体来说,有以下 2 点:
大家好,这里是 FEHub,每天早上 9 点更新,为你严选优质文章,与你一起进步。
如果喜欢这篇文章,记得点赞,转发。让你的好基友和你一样优秀。
微信后台回复关键字:「092c388d6169e78d」,即可参与红包抽奖,每晚 10 点开奖。
欢迎关注 「FEHub」,每天进步一点点
[1]
密码学: https://zh.wikipedia.org/wiki/%E5%AF%86%E7%A2%BC%E5%AD%B8
[2]
算法: https://zh.wikipedia.org/wiki/%E6%BC%94%E7%AE%97%E6%B3%95
[3]
密钥: https://zh.wikipedia.org/wiki/%E5%AF%86%E9%92%A5
[4]
明文: https://zh.wikipedia.org/wiki/%E6%98%8E%E6%96%87
[5]
密文: https://zh.wikipedia.org/wiki/%E5%AF%86%E6%96%87
[6]
对称加密: https://zh.wikipedia.org/wiki/%E5%AF%B9%E7%A7%B0%E5%8A%A0%E5%AF%86
[7]
安全协议: https://zh.wikipedia.org/wiki/%E5%AE%89%E5%85%A8%E5%8D%8F%E8%AE%AE
[8]
信道: https://zh.wikipedia.org/wiki/%E4%BF%A1%E9%81%93
[9]
密钥: https://zh.wikipedia.org/wiki/%E5%AF%86%E9%92%A5
[10]
对称密钥: https://zh.wikipedia.org/wiki/%E5%AF%B9%E7%A7%B0%E5%AF%86%E9%92%A5
[11]
加密: https://zh.wikipedia.org/wiki/%E5%8A%A0%E5%AF%86
[12]
知乎: https://www.zhihu.com/question/29383090
[13]
公开密钥基础建设: https://zh.wikipedia.org/wiki/%E5%85%AC%E9%96%8B%E9%87%91%E9%91%B0%E5%9F%BA%E7%A4%8E%E5%BB%BA%E8%A8%AD
[14]
公开密钥: https://zh.wikipedia.org/wiki/%E5%85%AC%E5%BC%80%E5%AF%86%E9%92%A5%E5%8A%A0%E5%AF%86
[15]
身份: https://zh.wikipedia.org/wiki/%E8%BA%AB%E5%88%86%E6%A0%87%E8%AF%86%E6%96%B9%E5%BC%8F
[16]
数字证书认证机构: https://zh.wikipedia.org/wiki/%E6%95%B0%E5%AD%97%E8%AF%81%E4%B9%A6%E8%AE%A4%E8%AF%81%E6%9C%BA%E6%9E%84
[17]
数字签名: https://zh.wikipedia.org/wiki/%E6%95%B8%E4%BD%8D%E7%B0%BD%E7%AB%A0
[18]
正确无误: https://zh.wikipedia.org/wiki/%E6%95%B0%E6%8D%AE%E5%AE%8C%E6%95%B4%E6%80%A7
[19]
cipher suite: https://zh.wikipedia.org/wiki/%E5%AF%86%E7%A0%81%E5%A5%97%E4%BB%B6
[20]
The SSL/TLS Handshake: an Overview: https://tweenpath.net/ssl-tls-handshake-overview/
[21]
https 是什么?使用 https 的好处与不足?: http://www.shuchengxian.com/article/634.html
[22]
RSA 的公钥和私钥到底哪个才是用来加密和哪个用来解密?: https://www.zhihu.com/question/25912483
[23]
Diffie-Hellman 密码交换是如何运作的?: https://www.zhihu.com/question/29383090
[24]
迪菲 - 赫尔曼密钥交换: https://zh.wikipedia.org/wiki/%E8%BF%AA%E8%8F%B2-%E8%B5%AB%E7%88%BE%E6%9B%BC%E5%AF%86%E9%91%B0%E4%BA%A4%E6%8F%9B
[25]
公开密钥认证: https://zh.wikipedia.org/wiki/%E5%85%AC%E9%96%8B%E9%87%91%E9%91%B0%E8%AA%8D%E8%AD%89
[26]
SSL/TLS 原理详解: https://www.linuxidc.com/Linux/2016-05/131147.htm
[27]
https 的 pre-master-secret 到 master-secret 的过程?: https://www.zhihu.com/question/54320042
[28]
Differences between the terms 'pre-master secret', 'master secret', 'private key', and 'shared secret'?: https://crypto.stackexchange.com/questions/27131/differences-between-the-terms-pre-master-secret-master-secret-private-key
[29]
How does SSL/TLS work?: https://security.stackexchange.com/questions/20803/how-does-ssl-tls-work
[30]
What's the point of the pre-master key? [duplicate]: https://security.stackexchange.com/questions/54399/whats-the-point-of-the-pre-master-key
[31]
The SSL/TLS Handshake: an Overview: https://tweenpath.net/ssl-tls-handshake-overview/