René's URL Explorer Experiment


Title: 带你看不一样的https · Issue #13 · wython/wython.github.io · GitHub

Open Graph Title: 带你看不一样的https · Issue #13 · wython/wython.github.io

X Title: 带你看不一样的https · Issue #13 · wython/wython.github.io

Description: 前言 https并不是一个协议,通常来说,如果我们说使用了https,意思是说,我们在http上使用了tls协议。 于是,我们可以更进一步的理解到: tls实际上不是特地为http服务的一个协议。 tls是应用层中比较下层的协议 tls可以应用于其他应用层协议,比如邮件 为什么我比较强调这种层次概念,因为知识的边界和概念需要划分清晰,在遇到问题,才能知道突破口是在哪。我看大部分关于https文章会一上来就讲一些握手过程,或者密码学原理相关的内容,或者有些文章甚至没有关于...

Open Graph Description: 前言 https并不是一个协议,通常来说,如果我们说使用了https,意思是说,我们在http上使用了tls协议。 于是,我们可以更进一步的理解到: tls实际上不是特地为http服务的一个协议。 tls是应用层中比较下层的协议 tls可以应用于其他应用层协议,比如邮件 为什么我比较强调这种层次概念,因为知识的边界和概念需要划分清晰,在遇到问题,才能知道突破口是在哪。我看大部分关于https...

X Description: 前言 https并不是一个协议,通常来说,如果我们说使用了https,意思是说,我们在http上使用了tls协议。 于是,我们可以更进一步的理解到: tls实际上不是特地为http服务的一个协议。 tls是应用层中比较下层的协议 tls可以应用于其他应用层协议,比如邮件 为什么我比较强调这种层次概念,因为知识的边界和概念需要划分清晰,在遇到问题,才能知道突破口是在哪。我看大部分关于https...

Opengraph URL: https://github.com/wython/wython.github.io/issues/13

X: @github

direct link

Domain: patch-diff.githubusercontent.com


Hey, it has json ld scripts:
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"带你看不一样的https","articleBody":"## 前言\r\nhttps并不是一个协议,通常来说,如果我们说使用了https,意思是说,我们在http上使用了tls协议。\r\n于是,我们可以更进一步的理解到:\r\n1. tls实际上不是特地为http服务的一个协议。\r\n2. tls是应用层中比较下层的协议\r\n3. tls可以应用于其他应用层协议,比如邮件\r\n\r\n为什么我比较强调这种层次概念,因为知识的边界和概念需要划分清晰,在遇到问题,才能知道突破口是在哪。我看大部分关于https文章会一上来就讲一些握手过程,或者密码学原理相关的内容,或者有些文章甚至没有关于协议本书的说明,而是仅仅讲抽象握手过程。我想,这样的理解并没有很结构化的去讲好这样一个东西,所以这也是我写这篇文章的初衷。\r\n\r\n为了容易理解,我会把比较结构性内容放在前面,把细节内容放在后面。\r\n## 宏观看tls\r\n上面一直在讲tls,对于事先没有了解过https的人来说,可能有点迷糊——tls是什么?\r\n了解过tls的人,应该也知道ssl协议。\r\n\r\n- TLS:全称是Transport Layer Security协议,意思就是传输层安全协议\r\n- SSL:全称是Secure Sockets Layer协议,意思是安全套接层协议\r\n\r\n从字面意思上来看,这两个东西差不多,实际上,这两个东西也可以认为是一样的概念。tls就是ssl升级之后的版本,在早期时候(1994),为了解决http本身的安全问题,网景公司创建了ssl协议应用于http协议,后来将ssl统一,应用于更广泛的应用层协议,进一步标准化ssl协议,也就是tls协议。\r\n\r\n可以把tls当成一层协议看待,那么其于http的关系类似于:\r\n\r\n![](https://user-gold-cdn.xitu.io/2020/7/2/1730d9d16be04705?w=594\u0026h=520\u0026f=png\u0026s=68118)\r\n\r\n### 为何需要tls\r\n上面提到,为了解决http存在的安全问题,所以引入tls协议。我们自然会有这样的疑问,是什么样的安全问题,需要在协议上去做文章。\r\n\r\n先总结这样三个问题:\r\n1. 数据隐私问题\r\n2. 数据被篡改问题\r\n3. 身份认证问题\r\n\r\n数据隐私:http协议是明文传输,也就是说如果中间人劫持请求,很容易理解到http协议传输内容的含义。有人可能会问:那我们平时通过加密传输不就可以解决了吗,为什么需要在协议中大动干戈。这里就需要点密码学的常识,如果仅仅是简单的加密数据,我们有三种可选密码方案,对称加密,非对称加密,单向散列或者mac算法,不管是对称加密和非对称加密,这意味着双方都需要有解密用的钥,对称加密用的是同一个密钥,非对称需要各有一把相对的钥匙。对于web这样面向客户端的传输,在客户端植入密钥明显是不现实的行为,所以可选方案中,密钥怎么安全传输变成了另一个问题,也是tls协议握手协议解决的问题。至于不可逆的加密,比如登录密码本身,对于中间人攻击,其实他并不需要知道你本身数据是什么,这样看似把数据隐私化,实际上并没有达到安全效果。\r\n\r\n数据被篡改:如果http协议没法防止被篡改。虽然有消息验证码,数字签名能保证数据完整。但是单纯一个密码技术依然很难防止中间人攻击\r\n\r\n身份认证问题:http是无状态协议,所以验证服务端身份是一件重要事情,证书认证也是https安全传输的一环\r\n\r\nhttp确实存在这样一些安全问题,虽然对使用者而言,确实有很多方法去预防安全问题,但是通过分析可以发现,没法用简单的方式,通过单一的一个种密码学算法就能解决这些问题,一般来说,会组合各种密码学算法,这是一个繁琐的工作,所以tls也是将这些繁琐的问题,统一成一个解决方案。\r\n### tls协议结构\r\ntls是介于应用层协议和tcp协议纸之间的协议,tls协议可以分成两层协议:\r\n1. 握手协议(TLS Handshaking Protocols)\r\n2. 记录层协议(TLS Record Protocol)\r\n\r\n结构如图:\r\n![](https://user-gold-cdn.xitu.io/2020/7/2/1730de1150bafc10?w=988\u0026h=286\u0026f=png\u0026s=66436)\r\n\r\n握手协议可以分成四个子协议:\r\n结构如图:\r\n\r\n![](https://user-gold-cdn.xitu.io/2020/7/2/1730de2455367212?w=1064\u0026h=188\u0026f=png\u0026s=58862)\r\n注:在tls 1.2版本之前,没有heartbeat心跳协议,而是change cipher spec protocol密码切换协议。\r\n\r\n记录层协议是接近tcp协议的底层协议,用来将握手协议定义消息封装和下层协议通讯。\r\n\r\n### 握手子协议\r\n握手协议可以说是tls中最重要的子协议,因为它的职责就是协商出一种合适的 **密码套件** 。上面也提到,解决一个安全问题不止一种加密算法,密码套件正是一组各种不同功能算法的集合。一般需要**两个来回**协商完成。\r\n\r\n握手协议中以**消息**为单位,消息格式如图:\r\n\r\n\r\n![](https://user-gold-cdn.xitu.io/2020/7/2/1730e2ec1c9113f5?w=1294\u0026h=412\u0026f=png\u0026s=81593)\r\n\r\n一个消息分成是三个部分:\r\n1. 消息长度:占用三个字节,用于定义消息最终长度大小\r\n2. 消息类型:占用一个字节,tls握手协议中有不同的消息类型,每个消息类型会带不同的数据。\r\n3. 消息内容:大于一个字节,这是消息的主体内容\r\n\r\ntls协议有十种不同的消息类型,分别是:\r\n1. hello_request: 0x00\r\n2. client_hello: 0x01\r\n3. server_hello: 0x02\r\n4. certificate: 0x0b\r\n5. server_key_exchange: 0x0c\r\n6. certificate_request: 0x0d\r\n7. servert_done: 0x0e\r\n8. certificate_verify:0x0f\r\n9. client_key_exchange:0x10\r\n10. finished: 0x14\r\n\r\n#### 握手过程\r\n握手过程一般是两个来回,主要用于交换不同的信息。tls1.2版本的握手过程,大体可以如图这样抽象表示:\r\n\r\n![](https://user-gold-cdn.xitu.io/2020/7/3/17313f0306dab14e?w=1502\u0026h=1080\u0026f=png\u0026s=225124)\r\n\r\n可以看到,在经过两个来回之后,客户端和服务端就正式进入数据传输。在握手端来回中,不难发现,一个请求可能会带好几个握手协议不同的消息类型。这是因为,虽然握手协议会把不同消息交给记录层协议,但是记录层协议一般会把几个类型封装成一个数据块发送。\r\n\r\n图中的*标记表示该消息会根据不同的密码套件做调整,[]标记表示该协议并不是握手协议定义的内容,但是也会在握手过程中进行。颜色较浅部分属于需要一个集合,绑定发送,这是双向认证需要的环节。\r\n\r\n接下来,就细看每一个消息的含义把\r\n\r\n#### Client Hello消息\r\n上面流程图中,客户端首先会发起一个消息,这个消息结构如下:\r\n``` c++\r\n struct {\r\n        ProtocolVersion client_version;\r\n        Random random;\r\n        SessionID session_id;\r\n        CipherSuite cipher_suites\u003c2..2^16-2\u003e;\r\n        CompressionMethod compression_methods\u003c1..2^8-1\u003e;\r\n        select (extensions_present) {\r\n            case false:\r\n                struct {};\r\n            case true:\r\n                Extension extensions\u003c0..2^16-1\u003e;\r\n        };\r\n} ClientHello; \r\n```\r\n\r\n该数据定义了6个key:\r\n1. client_version:表示支持的最高版本号\r\n2. random:客户端生出的随机数,这里你可以先记下,finished消息中用prf算法生产主密钥和密钥块会用到,生成预备主密钥也会用到,避免重放攻击。\r\n3. session_id:这个是会话重启相关的,建立过https连接的客户端可以保存服务器给的id,如果这个值存在,则会走会话重启的过程,而不是像项目那样完整的流程\r\n4. cipher_suites: 客户端支持的密码套件\r\n5. compresson_methods: 压缩算法,一般不会启用压缩算法\r\n6. extensions: 支持的扩展内容\r\n\r\n所以说,消息并不是很复杂。\r\n\r\n#### server_hello\r\n服务端的hello信息和客户端一样的结构\r\n``` c++\r\n  struct {\r\n        ProtocolVersion server_version;\r\n        Random random;\r\n        SessionID session_id;\r\n        CipherSuite cipher_suite;\r\n        CompressionMethod compression_method;\r\n        select (extensions_present) {\r\n            case false:\r\n                struct {};\r\n            case true:\r\n                Extension extensions\u003c0..2^16-1\u003e;\r\n        };\r\n} ServerHello;\r\n```\r\n具体就不重复描述了。\r\n\r\n#### server certificate消息\r\n这个消息是和上面的hello在一个请求的,可以看到,握手协议发送完server_hello情况以后就会发送certificate消息。但是由于,一些密码套件如DH_anon和DCDH_anon,不会发送该证书,所以该消息是可选的,但是大部分情况,都会用到证书信息。\r\n\r\n该消息主要承载证书信息,证书是做身份验证的,该消息结构如下:\r\n``` c++\r\n    opaque ASN.1Cert\u003c1..2^24-1\u003e;\r\n\r\n    struct {\r\n        ASN.1Cert certificate_list\u003c0..2^24-1\u003e;\r\n    } Certificate;\r\n```\r\n可以看到只有一个certificate_list数组,该数组发送的是证书链,用于证书认证。\r\n关于证书细节留到后面去讲述。\r\n\r\n#### server_key_exchange消息\r\n如果certificate消息里的证书信息不足以满足协商加密算法信息要求,会额外发送一个server_key_exchange信息作为补充。有6种密码套件是需要这个消息来发送的,如下:\r\n```\r\nDHE_DSS\r\nDHE_RSA\r\nECDHE_ECDSA\r\nECDHE_RSA\r\n------------------------\r\n// 无证书\r\nDH_anon\r\nECDH_anon\r\n```\r\n分割线之前的套件由于使用的临时的 DH/ECDH 密钥协商算法,证书中是不包含这些动态的 DH 信息(DH 参数和 DH 公钥),所以发送完证书信息之后会追加这个消息对DH信息做补充\r\n\r\n分割线下面的两种套件,属于匿名协商,没有证书信息,所以不会有certificate消息,但是由于需要发送额外的静态DH信息,所以会在这个消息里追加发送。\r\n\r\n对于不同公钥密码算法细节就不在这里讨论。\r\n#### certificate_request消息\r\n可以看到,服务器端可能会发送一个certificate_request消息。该消息是可选的,同时是灰色,我用灰色表示,为了说明该消息和其他灰色信息的关系,同时,一般也不会出现。但是在双向认证场景中,由于需要客户端也提供证书,所以服务端会发送这样信息,要求客户端也需要认证证书。\r\n\r\n#### server_hello_done消息\r\n上面流程图,在发送完sertificate和exchange信息之后,服务端会紧接一个server_hello_done类型消息作为结束。之后server会等待客户端后续的工作。该消息结构十分简单:\r\n``` c++\r\n struct { } ServerHelloDone;\r\n```\r\n#### client_certificate消息\r\n对于客户端的certificate消息,该消息表示,如果在收到服务端发送的消息里,包含certificate_request消息,则客户端会根据自身条件发送证书信息。如果没有客户端没有合适的证书信息,会发送一个空数组。\r\n\r\n#### client_key_exchange消息\r\n该消息无论如何都会发送,这个消息最大的作用是传递pre_master_key,也就是预备主密钥,除了预备主密钥,如果客户端需要发送上面的certificate消息,还会对类型DH算法密钥做补充信息。但是不管怎么,生成pre_master_key是最重要对事,生成对pre_master_key是用于生成**master_key**的重要前提,生成master_key会在双方拿到pre_master_key之后,在生成master_key之后,便会发送[ChangeCipherSpec]消息,转换状态。这意味着握手过程进入可以加密阶段。\r\n\r\n其含义可以参考上面服务端的server_key_exchange\r\n\r\n#### [ChangeCipherSpec]协议\r\n对于1.2版本的,在握手消息中,会涉及到协议状态转换,在1.3版本之后,该协议不在存在,但是为了向下兼容,握手中可能还会有。该协议是用于改变协议状态。\r\n\r\n可以理解为,在上述的握手过程中,收到该协议消息的端,状态都为:\r\n```\r\n    pending read status 待读状态\r\n    pending write status 待写状态\r\n```\r\n在接收到该信息之后,端状态修改为:\r\n```\r\n    current read status 可读状态\r\n    current write status 可写状态\r\n```\r\n该消息表示,在握手过程中,当进入可读可写状态时,表示对端将进入加密阶段,这也意味着,握手环节已经基本完成,具备加密传输的条件。\r\n\r\n#### finished消息\r\n在双方发送完,会对握手中的重要信息进行验证,验证双方会发送自己的校验信息,消息结构如下:\r\n```\r\n    struct {\r\n        opaque verify_data[verify_data_length];\r\n    } Finished;\r\n\r\n    verify_data = \r\n        PRF(master_secret, finished_label, Hash(handshake_messages))\r\n        [0..verify_data_length-1];\r\n```\r\n该消息的意义在于:握手过程中所有的子消息都没有加密和完整性保护,消息很容易篡改。为了避免握手期间存在消息被篡改的情况,所以 Client 和 Server 都需要校验一下对方的 Finished 子消息。\r\n\r\n完成finish消息之后,最后双方的通讯会以master_key作为对称加密信息的主密钥。\r\n\r\n\r\n以上,是tls1.2定义的握手内容,当然,还有很多细节没有研究,比如握手中涉及到的随机数,session_id的作用。不过大体的过程已经讲完了,后续慢慢补充一些细节。细节部分则需要一点密码学常识。\r\n\r\n## 细看tls\r\n如果想更深入理解,则需要了解部分密码学相关内容,像上面提到的对称加密,非对称加密,随机数,均属于密码学的内容。\r\n\r\n### 密码学常识\r\n这里简单的介绍几个密码学概念,他们分别是:\r\n- 随机数\r\n- 单向散列函数(hash算法)\r\n- 消息验证码(mac算法)\r\n- 数字签名\r\n- 对称加密算法\r\n- 公钥加密算法\r\n\r\n#### 随机数算法\r\n随机数作为重要的**密码学单元**,在密码学中广泛运用到,密码学单元是指:在其他算法中,随机数会产当一个因子的作用。比如生成对称密码和消息验证码。\r\n\r\n随机数有三个重要的特性:\r\n- 随机性\r\n- 不可预测性\r\n- 不可重新性\r\n\r\n三个特性关系可以表示为:\r\n![](https://user-gold-cdn.xitu.io/2020/7/3/1731464817f38599?w=912\u0026h=558\u0026f=png\u0026s=80471)\r\n\r\n一般我们把具有不可重现性的随机数叫**真随机数**,把具有不可预知的随机数叫**强伪随机数**,把具有随机性的随机数叫**伪随机数**。\r\n\r\n只有至少具有强伪随机数特性的随机数算法才能用于密码学。\r\n\r\n#### 单向散列函数\r\n单向散列函数即one-way hash function。就是我们常说的hash算法,对于用过md5算法的小伙伴应该不陌生。但是需要注意的是,单向散列函数的作用是保证消息的完整性。\r\n\r\n单向散列函数具有这样的特点:\r\n- 不同消息能达到固定长度的散列值\r\n- 抗碰撞,不同消息得到的散列值不同\r\n- 单向性,无法通过散列值获得原值\r\n- 高效\r\n\r\n关于强抗碰撞和弱抗碰撞:\r\n- 强抗碰撞:对于任意散列值,找到相同消息的困难度\r\n- 弱抗碰撞:对于一个消息和其散列值,找到另外一条不同消息,和该散列值相同的困难度\r\n\r\n通过特点我们可以很容易的知道,单向散列可以用来比较消息的完整性。因为其足够小,足够快,用来校验不同内容是否完整很有用。\r\n\r\n缺陷:\r\n当然,这也暴露了,单向散列函数的局限性,就是无法防止被篡改,也无法验证信息的来源。无法防止篡改,是因为攻击者很容易的可以将不同消息生成散列并且伪装。比如中间人攻击。\r\n\r\n常见散列算法:\r\n- MD5\r\n- SHA(secure hash algorithms),SHA-1,SHA-2(256,512,224,384),SHA-3(256,5`1,224,384)\r\n\r\n#### 对称加密算法\r\n加密和解密都是用同一个密钥的加密算法,叫对称加密算法。对称加密算法是在传输数据双方持有一个相同的密钥,这种算法需要解决最大问题就是密钥的传输问题。\r\n常见的对称加密有AES,DES。\r\n\r\n![](https://user-gold-cdn.xitu.io/2020/7/7/17327de2b741229b?w=1470\u0026h=480\u0026f=png\u0026s=92831)\r\n\r\n#### 公钥密码算法\r\n公钥密码算法就是非对称加密算法,由于前面提到的对称加密算法的局限性,所以很自然而然的联想到,是否有一种传输数据双方使用不同的密钥的算法。公钥密码算法的解密模型也很简单:\r\n\r\n![](https://user-gold-cdn.xitu.io/2020/7/7/17328a54ed3d4121?w=1238\u0026h=492\u0026f=png\u0026s=89786)\r\n\r\n这里需要提下,公钥加密算法确实有更多可能性,但是我发现很多人有一些理解误区:\r\n1. 就是非对称就比对称更优秀,或者说,更机密。我想这是不正确的,因为就机密性来说,取决于算法的密钥长度,同时非对称加密的性能很差,很难说同样机密性,非对称加密能做的比对称加密好。\r\n2. 认为非对称加密可以解决中间人攻击,非对称加密是解决不了中间人攻击的,因为中间人只要劫持了公钥,就能神不知鬼不觉的替换掉原来公钥,用自己伪造的伪公钥和伪密钥瞒天过海。\r\n3. 非对称算法在于它有使得传输过程中有更多可选方案,比如数字签名和密钥协商中,都会用到非对称加密的非对称密钥,这才是公钥算法的重要意义。\r\n\r\n目前最常用的公钥加密算法是RSA算法和ECC算法。\r\n\r\n关于这两个算法细节,这里就不花时间描述了。ECC算法相对密钥比RSA算法短,同时效率和机密性比RSA高。\r\n\r\n公钥加密算法的缺点就是执行效率太慢。\r\n\r\n#### 消息验证码(MAC)\r\n消息验证码(message authentication code)是一种确认完整性,并认证的技术。简称MAC算法。\r\n\r\n关于mac算法的理解需要结合之前的单向散列算法来看。我们知道,单向散列算法可以保证消息的完整性。\r\n\r\n![](https://user-gold-cdn.xitu.io/2020/7/7/173294750272c5a2?w=938\u0026h=732\u0026f=png\u0026s=112871)\r\n\r\n先看看两者的对比。\r\n\r\nMAC算法相对单向散列算法而言,多了一个共享密钥才能生成MAC值。这样很容易联想到,如何在网络中传输密钥是MAC算法的一个问题,这个问题和对称加密算法中的问题一样。\r\n\r\n那MAC算法相对HASH算法解决了什么问题呢,我们知道,如果中间人攻击了HASH算法生成的HASH值。由于HASH算法和MAC算法不关注消息的机密性,所以中间人可以对消息进行修改,同时用HASH算法重新生成HASH值从而达到篡改数据的效果。虽然MAC算法的密钥如果被中间人劫持,一样会遭受同样的问题,但是我们如果有一种方案,能够保证Mac密钥不被劫持,就能防止中间人攻击,这就是Mac算法存在的意义。\r\n\r\n所以,在MAC算法密钥安全的情况下。mac能保证消息完整,同时能够认证,认证的含义是只有持有密钥的人可以生成mac值。\r\n\r\n那mac算法的有没有其局限性,除了说mac算法本身不是为了机密性而生之外,mac算法依然无法反正抵赖问题。如何理解抵赖?\r\n\r\n我们假设作为第三者角度而言,用mac算法认证的消息虽然是完整的,但是如果有一天有一方对这个消息不承认,由于发送方和接收方都有密钥生成mac值,所以我们无法单从mac值中判断说,这个消息是谁生成的。这就需要用到后面介绍的数字签名技术。\r\n\r\n#### 数字签名\r\n数字签名,是一种能够认证消息来源,保证数据准确性,防止篡改的技术。关于数字签名,依然需要和单向散列算法和MAC算法做一个对比。\r\n\r\n单向散列算法可以保证消息完整准确性,含义在于只能保证在信息传输中不存在异常。但是无法防止如中间人攻击之类的,篡改数据,同时也无法对消息进行认证。\r\n\r\nMac算法可以保证消息准确同时,因为有一个共享密钥,所以只要保证密钥安全,就能反正数据被篡改,但是由于数据传输双方对密钥是相同的,无法通过第三方得知消息是谁发送的,即不能防止抵赖。\r\n\r\n数字签名在借助公钥密码算法的密钥不同的特点,实现了消息认证的机制。原理很简单,就是生成消息的一方通过密钥生成签名,接受消息的一方,可以通过公钥解开消息然后认证消息的正确性。为什么数字签名可以反正抵赖,因为只有持有公钥的人才能验证消息,只有持有密钥的人才能生成签名。这样双方都无法抵赖,同时也能保证消息的完整性,同样能反正篡改。\r\n\r\n关于数字签名的简单流程:\r\n\r\n![](https://user-gold-cdn.xitu.io/2020/7/8/1732c77ebefeb589?w=980\u0026h=942\u0026f=png\u0026s=167826)\r\n\r\n由于签名提到非对称加密算法的性能很差,所以上面流程的比对,性能自然也不好,原因是消息的长度可能很长,同时,对于rsa算法而言,需要加密的消息越长,其密钥公钥长度也要越长。聪明同学很容易联想到,使用单向散列算法可以使消息生成简单的hash值,同时,单向散列算法性能也很好。这样就解决了这个问题,所以,一般的签名算法流程优化如下:\r\n\r\n![](https://user-gold-cdn.xitu.io/2020/7/8/1732c7fc9deb8eec?w=1040\u0026h=1010\u0026f=png\u0026s=200937)\r\n\r\n补充:这里做一点补充,在数字签名里,非对称加密算法,通过密钥加密生成签名,通过公钥解密验证签名。而在使用rsa做加密操作时,一般会用公钥加密数据传输,而不会通过密钥加密数据传输。原因是因为,公钥是公开对,任何人都可能获得,如果通过密钥加密数据,任何人都可能拿到公钥然后解密。\r\n\r\n#### 密钥协商算法\r\n回顾前面的技术,消息认证码(MAC),对称加密,以及用到这些技术的地方,都要强调密钥重要性。但是在网络传输过程中,为了双方都能持有相同密钥。我们会思考如何传输密钥。\r\n\r\n这个就是密钥如何配送的问题,关于解决密钥配送问题,有以下几种方式:\r\n1. 事先共享密钥:比如直接在浏览器和服务器里面事先内置需要的密钥,这显然是不太现实的做法\r\n2. 密钥中心分配:建立一个专门管理密钥的中心,由它来分配,但是这样存储量和维护成本就很大。\r\n3. 基于非对称算法实现:由拿到公钥的一端负责生成主密钥,并且用公钥加密发送主密钥。这样就能防止泄密,因为只有密钥持有者可以解密主密钥。但是单纯的这种方式会由中间人攻击问题,要配合证书认证公钥合法。\r\n4. 基于DH算法实现:DH算法会在两端都保留各种私有信息,并且通过传输部分公共信息,两边通过公共信息生成主密钥。而即使公共信息被拿到,第三方也无法通过公共信息生成主密钥,从而达到传输密钥都效果。\r\n\r\n这里只讲下DH的简单过程,关于用非对称算法传输密钥很好理解,就不再这里描述:\r\n\r\n![](https://user-gold-cdn.xitu.io/2020/7/16/1735642920c7d23d?w=1472\u0026h=736\u0026f=png\u0026s=138973)\r\n\r\n在上面流程中,G,P,G^AmodP和G^BmodP是四个公开的数字。但是要通过这四个数字算出A,B数是很难的。\r\n\r\n生成元G的意义:\r\nG的计算是比较复杂的,对于G^XmodP (1 \u003c x \u003c p 内的整数)的所有值都不同时,G就是P的元。而A,B随机取0到P之间的所有整数。这样,A,B有足够多的选择,同时计算有足够多的可能性。\r\n\r\nDH算法能防止中间人攻击吗?不能,中间人依然可以通过中间篡改伪造A和B达到中间人攻击的效果。\r\n\r\nDH算法可以和RSA这类非对称算法做签名,从而抵御中间人攻击。\r\nDH算法和ECC算法进行结合升级新的密钥写书协商算法即是ECDH。\r\n\r\n#### 证书认证\r\n证书认证的意义是给公钥加上签名,RSA算法在做密钥协商,或者数据加密时。都可能被中间人给劫持伪造。但是如果有一种技术能够识别,公钥有没有被伪造,那就能够防止中间人攻击。\r\n\r\n这样我们很容易联想到我们之前谈论到数字签名技术,因为数字签名不仅能保证数据不被篡改,还能防止抵赖。但是,聪明的你应该很容易联想到,数字签名也是要用公钥算法做签名。怎么保证签名都机构都公钥安全又是另一个问题。\r\n\r\n于是,我们想象如果有这样一个机构,他用自己都私钥给客户都公钥进行签名。然后这样都机构公开自己都公钥,因为中间人没有机构都私钥,这样中间人无法伪造签名。就无法伪造客户都公钥了。\r\n\r\n这样又有新都问题,我们凭什么想象这个机构。事实到这里,我们确实只能想象这个机构,别无他法。这个机构就是CA机构。\r\n\r\n所以,证书其实就是给客户的公钥和信息加上一个数字签名,有了这个数字签名。就没法伪造公钥。\r\n\r\n但是,新的问题是,在做数字签名认证时,我们需要用到CA机构的公钥进行认证,如果通过网络的方式去获取公钥,这个公钥有没可能被攻击者劫持,是有可能的。所以比较好的做法是把CA机构的信息内置到操作系统中。不通过网络获取。但是如果CA机构的数量过于庞大,怎么办。所以实际上,CA机构分为 **CA根机构** 和 **CA中间机构**。在操作系统中只要内置根证书就行了。通过根证书给下一级机构签名,而中间机构通过网络传输也没有关系,只要更证书是安全的,就能通过签名发现中间机构是否被伪造。这样就解决了传输问题。\r\n\r\n### 再看握手过程\r\n![](https://user-gold-cdn.xitu.io/2020/7/3/17313f0306dab14e?w=1502\u0026h=1080\u0026f=png\u0026s=225124)\r\n通过前面关于密码学的了解。这里可以更深入的去思考握手过程。\r\n这次我们先明确握手的目的,看上图中的过程,握手过程最终是为了数据传输服务的。也就是后续数据传输中的application data过程。\r\n\r\n#### 记录层协议\r\n数据传输是在记录层协议中的定义的,关于记录层协议,主要是完成一下的功能:\r\n1. 装载由上层协议分发下来的消息\r\n2. 有选择的压缩数据\r\n3. 对数据进行加密,解密和mac认证\r\n\r\n所以,在握手结束后,一般会采用对称加密算法加密数据,然后做mac认证。握手过程为了给传输数据提供**会话密钥**。而tls 1.2版本在PRF函数中使用加密基元是 **SHA256** 算法。\r\n\r\n在握手过程中,最终会生成三个密钥分别是:\r\n1. 预备主密钥(pre_master_key)\r\n2. 主密钥(master_key)\r\n3. 会话密钥(session_master_key)\r\n\r\n在前面的握手过程中,我们看到第一个来回,协商了主要的密码套件,并且客户端和服务端交换了以一对随机数,分别是client_random,和server_random。忘记的回去看hello消息的结构。\r\n\r\n上面的主密钥是通过PRF函数和随机数计算得来:\r\n```\r\nPRF(pre_master_secret, \"master secret\",\r\n    ClientHello.random + ServerHello.random)\r\n    [0..47];\r\n```\r\n计算时间前面提到过,是在校验完证书之后。\r\n\r\n以rsa协商为例,预备主密钥,则由客户端随机生成,然后通过公钥发送,也就是client_key_exchange的那个消息中生成。\r\n\r\n这里可以根据密码学原理提出几个解答:\r\n1. 为什么是由客户端生成预备主密钥中,通过公钥加密发送。\r\n答:在前面提到的rsa密钥协商中,通过公钥一方去发送密钥信息,第三方无法解密出密钥信息,因为第三方必须用非对称中的私钥去解密,但是私钥是不公开的。相反,如果是通过私钥加密,则由于公钥是公开的,第三方很容易解密得到密钥。\r\n\r\n2. 如果是dh算法相关的协商,如何获取到预备主密钥。\r\n答:加入不是rsa作为密钥协商,那么双方会在exchange信息中交换公共信息,然后计算出预备主密钥,预备主密钥就不会进行网络传输。本质上是没有变化的。\r\n\r\n3. 在1问题中,通过rsa密钥协商不是会遭遇中间人攻击吗?\r\n答:密码学章节已经讲过,证书技术是如何防止中间人攻击的,也就是经过证书签名的公钥是安全的,中间人无法伪造。所以不会有中间人攻击。\r\n\r\n而会话密钥是记录层中通过主密钥生成的数据。该数据会被拆成几部分,分别用于加密解密,和mac认证。\r\n\r\n#### 会话重启\r\ntls 1.2有两种会话重启的方式,分别:\r\n1. 基于Session Id\r\n2. 基于Session Ticket\r\n\r\n基于Session Id流程:\r\n\r\n![](https://user-gold-cdn.xitu.io/2020/7/17/1735b6c6f6f4e852?w=1450\u0026h=792\u0026f=png\u0026s=139278)\r\n\r\n基于session的方式,在客户端发送第一个hello的时候,会带上消息中的session_id,该id是在完整握手中由服务器生成,并且保存在服务器内存中。\r\n会话重启中会保留之前的主密钥,会话密钥会重新生成。这样可以防止前向安全性。\r\n\r\n这种重启方式有session的通病,就是比较占用服务器资源,因为session是服务器生成并且保存在服务器中。\r\n\r\n相比session的重启方式,基于ticket的方式就是在客户端存储会话,服务端不做存储。不过每次重启会更新ticket。流程如下:\r\n\r\n![](https://user-gold-cdn.xitu.io/2020/7/17/1735b728c63f3e76?w=1434\u0026h=798\u0026f=png\u0026s=158487)\r\n\r\n参考资料:\r\n1. \u003c\u003c图解密码学\u003e\u003e\r\n2. \u003c\u003c深入浅出https\u003e\u003e\r\n3. [https](https://github.com/halfrost/Halfrost-Field)\r\n","author":{"url":"https://github.com/wython","@type":"Person","name":"wython"},"datePublished":"2020-07-17T06:51:33.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/13/wython.github.io/issues/13"}

route-pattern/_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format)
route-controllervoltron_issues_fragments
route-actionissue_layout
fetch-noncev2:6759391c-8ec7-436b-d7cd-d5fe77855601
current-catalog-service-hash81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114
request-id99D0:20FD81:217DC05:2AE0B3E:6975624D
html-safe-nonce67471e87e1a5230a6cccafe3e2ffc4b1e704f895b2d7c297d7471f7a6efaf17a
visitor-payloadeyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI5OUQwOjIwRkQ4MToyMTdEQzA1OjJBRTBCM0U6Njk3NTYyNEQiLCJ2aXNpdG9yX2lkIjoiNDY5Njg1MzE3Mjk3Njk2ODI2OSIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9
visitor-hmacea397d92035d1ab68d624df9f7447faf971cb03d7b89d70f159c349885b932d0
hovercard-subject-tagissue:658933973
github-keyboard-shortcutsrepository,issues,copilot
google-site-verificationApib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I
octolytics-urlhttps://collector.github.com/github/collect
analytics-location///voltron/issues_fragments/issue_layout
fb:app_id1401488693436528
apple-itunes-appapp-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/wython/wython.github.io/13/issue_layout
twitter:imagehttps://opengraph.githubassets.com/7c9f7b775ed95b658bcfc1fd1fd303121a65836ee7a9b6cab0135f3fc0f029e2/wython/wython.github.io/issues/13
twitter:cardsummary_large_image
og:imagehttps://opengraph.githubassets.com/7c9f7b775ed95b658bcfc1fd1fd303121a65836ee7a9b6cab0135f3fc0f029e2/wython/wython.github.io/issues/13
og:image:alt前言 https并不是一个协议,通常来说,如果我们说使用了https,意思是说,我们在http上使用了tls协议。 于是,我们可以更进一步的理解到: tls实际上不是特地为http服务的一个协议。 tls是应用层中比较下层的协议 tls可以应用于其他应用层协议,比如邮件 为什么我比较强调这种层次概念,因为知识的边界和概念需要划分清晰,在遇到问题,才能知道突破口是在哪。我看大部分关于https...
og:image:width1200
og:image:height600
og:site_nameGitHub
og:typeobject
og:author:usernamewython
hostnamegithub.com
expected-hostnamegithub.com
None4a4bf5f4e28041a9d2e5c107d7d20b78b4294ba261cab243b28167c16a623a1f
turbo-cache-controlno-preview
go-importgithub.com/wython/wython.github.io git https://github.com/wython/wython.github.io.git
octolytics-dimension-user_id15258919
octolytics-dimension-user_loginwython
octolytics-dimension-repository_id142893945
octolytics-dimension-repository_nwowython/wython.github.io
octolytics-dimension-repository_publictrue
octolytics-dimension-repository_is_forkfalse
octolytics-dimension-repository_network_root_id142893945
octolytics-dimension-repository_network_root_nwowython/wython.github.io
turbo-body-classeslogged-out env-production page-responsive
disable-turbofalse
browser-stats-urlhttps://api.github.com/_private/browser/stats
browser-errors-urlhttps://api.github.com/_private/browser/errors
release488b30e96dfd057fbbe44c6665ccbc030b729dde
ui-targetfull
theme-color#1e2327
color-schemelight dark

Links:

Skip to contenthttps://patch-diff.githubusercontent.com/wython/wython.github.io/issues/13#start-of-content
https://patch-diff.githubusercontent.com/
Sign in https://patch-diff.githubusercontent.com/login?return_to=https%3A%2F%2Fgithub.com%2Fwython%2Fwython.github.io%2Fissues%2F13
GitHub CopilotWrite better code with AIhttps://github.com/features/copilot
GitHub SparkBuild and deploy intelligent appshttps://github.com/features/spark
GitHub ModelsManage and compare promptshttps://github.com/features/models
MCP RegistryNewIntegrate external toolshttps://github.com/mcp
ActionsAutomate any workflowhttps://github.com/features/actions
CodespacesInstant dev environmentshttps://github.com/features/codespaces
IssuesPlan and track workhttps://github.com/features/issues
Code ReviewManage code changeshttps://github.com/features/code-review
GitHub Advanced SecurityFind and fix vulnerabilitieshttps://github.com/security/advanced-security
Code securitySecure your code as you buildhttps://github.com/security/advanced-security/code-security
Secret protectionStop leaks before they starthttps://github.com/security/advanced-security/secret-protection
Why GitHubhttps://github.com/why-github
Documentationhttps://docs.github.com
Bloghttps://github.blog
Changeloghttps://github.blog/changelog
Marketplacehttps://github.com/marketplace
View all featureshttps://github.com/features
Enterpriseshttps://github.com/enterprise
Small and medium teamshttps://github.com/team
Startupshttps://github.com/enterprise/startups
Nonprofitshttps://github.com/solutions/industry/nonprofits
App Modernizationhttps://github.com/solutions/use-case/app-modernization
DevSecOpshttps://github.com/solutions/use-case/devsecops
DevOpshttps://github.com/solutions/use-case/devops
CI/CDhttps://github.com/solutions/use-case/ci-cd
View all use caseshttps://github.com/solutions/use-case
Healthcarehttps://github.com/solutions/industry/healthcare
Financial serviceshttps://github.com/solutions/industry/financial-services
Manufacturinghttps://github.com/solutions/industry/manufacturing
Governmenthttps://github.com/solutions/industry/government
View all industrieshttps://github.com/solutions/industry
View all solutionshttps://github.com/solutions
AIhttps://github.com/resources/articles?topic=ai
Software Developmenthttps://github.com/resources/articles?topic=software-development
DevOpshttps://github.com/resources/articles?topic=devops
Securityhttps://github.com/resources/articles?topic=security
View all topicshttps://github.com/resources/articles
Customer storieshttps://github.com/customer-stories
Events & webinarshttps://github.com/resources/events
Ebooks & reportshttps://github.com/resources/whitepapers
Business insightshttps://github.com/solutions/executive-insights
GitHub Skillshttps://skills.github.com
Documentationhttps://docs.github.com
Customer supporthttps://support.github.com
Community forumhttps://github.com/orgs/community/discussions
Trust centerhttps://github.com/trust-center
Partnershttps://github.com/partners
GitHub SponsorsFund open source developershttps://github.com/sponsors
Security Labhttps://securitylab.github.com
Maintainer Communityhttps://maintainers.github.com
Acceleratorhttps://github.com/accelerator
Archive Programhttps://archiveprogram.github.com
Topicshttps://github.com/topics
Trendinghttps://github.com/trending
Collectionshttps://github.com/collections
Enterprise platformAI-powered developer platformhttps://github.com/enterprise
GitHub Advanced SecurityEnterprise-grade security featureshttps://github.com/security/advanced-security
Copilot for BusinessEnterprise-grade AI featureshttps://github.com/features/copilot/copilot-business
Premium SupportEnterprise-grade 24/7 supporthttps://github.com/premium-support
Pricinghttps://github.com/pricing
Search syntax tipshttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
documentationhttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
Sign in https://patch-diff.githubusercontent.com/login?return_to=https%3A%2F%2Fgithub.com%2Fwython%2Fwython.github.io%2Fissues%2F13
Sign up https://patch-diff.githubusercontent.com/signup?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fvoltron%2Fissues_fragments%2Fissue_layout&source=header-repo&source_repo=wython%2Fwython.github.io
Reloadhttps://patch-diff.githubusercontent.com/wython/wython.github.io/issues/13
Reloadhttps://patch-diff.githubusercontent.com/wython/wython.github.io/issues/13
Reloadhttps://patch-diff.githubusercontent.com/wython/wython.github.io/issues/13
wython https://patch-diff.githubusercontent.com/wython
wython.github.iohttps://patch-diff.githubusercontent.com/wython/wython.github.io
Notifications https://patch-diff.githubusercontent.com/login?return_to=%2Fwython%2Fwython.github.io
Fork 0 https://patch-diff.githubusercontent.com/login?return_to=%2Fwython%2Fwython.github.io
Star 10 https://patch-diff.githubusercontent.com/login?return_to=%2Fwython%2Fwython.github.io
Code https://patch-diff.githubusercontent.com/wython/wython.github.io
Issues 14 https://patch-diff.githubusercontent.com/wython/wython.github.io/issues
Pull requests 0 https://patch-diff.githubusercontent.com/wython/wython.github.io/pulls
Actions https://patch-diff.githubusercontent.com/wython/wython.github.io/actions
Projects 0 https://patch-diff.githubusercontent.com/wython/wython.github.io/projects
Security 0 https://patch-diff.githubusercontent.com/wython/wython.github.io/security
Insights https://patch-diff.githubusercontent.com/wython/wython.github.io/pulse
Code https://patch-diff.githubusercontent.com/wython/wython.github.io
Issues https://patch-diff.githubusercontent.com/wython/wython.github.io/issues
Pull requests https://patch-diff.githubusercontent.com/wython/wython.github.io/pulls
Actions https://patch-diff.githubusercontent.com/wython/wython.github.io/actions
Projects https://patch-diff.githubusercontent.com/wython/wython.github.io/projects
Security https://patch-diff.githubusercontent.com/wython/wython.github.io/security
Insights https://patch-diff.githubusercontent.com/wython/wython.github.io/pulse
New issuehttps://patch-diff.githubusercontent.com/login?return_to=https://github.com/wython/wython.github.io/issues/13
New issuehttps://patch-diff.githubusercontent.com/login?return_to=https://github.com/wython/wython.github.io/issues/13
带你看不一样的httpshttps://patch-diff.githubusercontent.com/wython/wython.github.io/issues/13#top
httpshttps://github.com/wython/wython.github.io/issues?q=state%3Aopen%20label%3A%22https%22
tlshttps://github.com/wython/wython.github.io/issues?q=state%3Aopen%20label%3A%22tls%22
https://github.com/wython
https://github.com/wython
wythonhttps://github.com/wython
on Jul 17, 2020https://github.com/wython/wython.github.io/issues/13#issue-658933973
https://camo.githubusercontent.com/7e9992c120ac9a3215804884bbb5e208eda447e6dc0f0691fcaf2fb6a854cffd/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323032302f372f322f313733306439643136626530343730353f773d35393426683d35323026663d706e6726733d3638313138
https://camo.githubusercontent.com/782ec94afdfb091435515cbd039168a376f4fc08ec47ae0bac226def3165afb5/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323032302f372f322f313733306465313135306261666331303f773d39383826683d32383626663d706e6726733d3636343336
https://camo.githubusercontent.com/6a50bd60194fcdbba9376707eccf61f350f247bc1effb5dffb2f20f473ba1d6b/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323032302f372f322f313733306465323435353336373231323f773d3130363426683d31383826663d706e6726733d3538383632
https://camo.githubusercontent.com/efc701e83a87afcf784eb72f8c63b5f6a34e0d521efbf6987bfb2cb6f1edb99a/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323032302f372f322f313733306532656331633931313366353f773d3132393426683d34313226663d706e6726733d3831353933
https://camo.githubusercontent.com/3fca0d01ab801325c75338674c6f42dafb68cd4fea8601601f41651634cc593e/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323032302f372f332f313733313366303330366461623134653f773d3135303226683d3130383026663d706e6726733d323235313234
https://camo.githubusercontent.com/42c1ac6e11b7166ce634331db0f6a73fef234c46c84bcec7fe051e6b7e23446f/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323032302f372f332f313733313436343831376633383539393f773d39313226683d35353826663d706e6726733d3830343731
https://camo.githubusercontent.com/9e288ec9e1c4b78bd4c1fb93dca1103f4f2493a20d2e1a043efe6684004bce52/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323032302f372f372f313733323764653262373431323239623f773d3134373026683d34383026663d706e6726733d3932383331
https://camo.githubusercontent.com/7e88349aa7b2649345a51f9feac59cfceb62649bdab948f218d66180182453a3/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323032302f372f372f313733323861353465643364343132313f773d3132333826683d34393226663d706e6726733d3839373836
https://camo.githubusercontent.com/7305238a97887e3ab4e4be665f54aa7a04a9e2de73e2cc82b3440ababdae9841/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323032302f372f372f313733323934373530323732633561323f773d39333826683d37333226663d706e6726733d313132383731
https://camo.githubusercontent.com/9bf1013b9e57da52ddfb42544e6305f116a2de4db9e0b452f25a1a05db430f9d/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323032302f372f382f313733326337376562656665623538393f773d39383026683d39343226663d706e6726733d313637383236
https://camo.githubusercontent.com/3ef3ab104edb736f012d490ec7b29eb8891265f5c20096c175c58db7deb356bc/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323032302f372f382f313733326337666339646562386565633f773d3130343026683d3130313026663d706e6726733d323030393337
https://camo.githubusercontent.com/97c30aaa0895286f17d8978fb792a77d20009ab7a62ee875fb858c69d7f7cc5a/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323032302f372f31362f313733353634323932306337643233643f773d3134373226683d37333626663d706e6726733d313338393733
https://camo.githubusercontent.com/3fca0d01ab801325c75338674c6f42dafb68cd4fea8601601f41651634cc593e/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323032302f372f332f313733313366303330366461623134653f773d3135303226683d3130383026663d706e6726733d323235313234
https://camo.githubusercontent.com/37c78e78e7512dac1fefaeec1b96f86a54db3276c51c22f3e141d78062dfe087/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323032302f372f31372f313733356236633666366634653835323f773d3134353026683d37393226663d706e6726733d313339323738
https://camo.githubusercontent.com/ae9d5645b6ac402383849361f3b1ab21df6145aba6502fc538274794672a1481/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323032302f372f31372f313733356237323863363366336537363f773d3134333426683d37393826663d706e6726733d313538343837
httpshttps://github.com/halfrost/Halfrost-Field
httpshttps://github.com/wython/wython.github.io/issues?q=state%3Aopen%20label%3A%22https%22
tlshttps://github.com/wython/wython.github.io/issues?q=state%3Aopen%20label%3A%22tls%22
https://github.com
Termshttps://docs.github.com/site-policy/github-terms/github-terms-of-service
Privacyhttps://docs.github.com/site-policy/privacy-policies/github-privacy-statement
Securityhttps://github.com/security
Statushttps://www.githubstatus.com/
Communityhttps://github.community/
Docshttps://docs.github.com/
Contacthttps://support.github.com?tags=dotcom-footer

Viewport: width=device-width


URLs of crawlers that visited me.