⽹络原理-HTTP/HTTPS
HTTP
HTTP是什么
HTTP(全称为"超⽂本
传输协议")是⼀种应⽤⾮常⼴泛的应⽤层协议.
HTTP往往是基于传输层的TCP协议实现的.(HTTP1.0,HTTP1.1,HTTP2.0均为TCP,HTTP3基于 UDP实现) ⽬前我们主要使⽤的还是HTTP1.1和HTTP2.0.
我们平时打开⼀个⽹站,就是通过HTTP协议来传输数据的.
当我们在浏览器中输⼊⼀个搜狗搜索的"⽹址"(URL)时,浏览器就给搜狗的服务器发送了⼀个HTTP 请求,搜狗的服务器返回了⼀个HTTP响应. 这个响应结果被浏览器解析之后,就展⽰成我们看到的⻚⾯内容.(这个过程中浏览器可能会给服务器发 送多个HTTP请求,服务器会对应返回多个响应,这些响应⾥就包含了⻚⾯HTML,CSS,JavaScript,图 ⽚,字体等信息).
所谓"超⽂本"的含义,就是传输的内容不仅仅是⽂本(⽐如html,css这个就是⽂本),还可以是⼀些其 他的资源,⽐如图⽚,视频,⾳频等⼆进制的数据.
理解"应⽤层协议"
我们已经学过 [ I TCP/IP ,已经知道⽬前数据能从客⼾端进程经过路径选择跨⽹络传送到服务器端进程 P+Port ].
可是,仅仅把数据从A点传送到B点就完了吗?
这就好⽐,在淘宝上买了⼀部⼿机,卖家[客⼾端]把⼿机通过顺丰[传送+路径选择]送到买家[服务 器]⼿⾥就完了吗?
当然不是,买家还要使⽤这款产品,还要在使⽤之后,给卖家打分评论。
所以,我们把数据从A端传送到B端, TCP/IP 解决的是顺丰的功能,⽽两端还要对数据进⾏加⼯处理 或者使⽤,所以我们还需要⼀层协议,不关⼼通信细节,关⼼应⽤细节!
这层协议叫做应⽤层协议。⽽应⽤是有不同的场景的,所以应⽤层协议是有不同种类的,其中经典协 议之⼀的HTTP就是其中的佼佼者.
再回到我们刚刚说的买⼿机的例⼦,顺丰相当于 TCP/IP 的功能,那么买回来的⼿机都附带了说明 书【产品介绍,使⽤介绍,注意事项等】,⽽该说明书指导⽤⼾该如何使⽤⼿机【虽然我们都不看, 但是⽗⺟辈有部分是有看说明书的习惯的:)】,此时的说明书可以理解为⽤⼾层协议
理解HTTP协议的⼯作过程
当我们在浏览器中输⼊⼀个"⽹址",此时浏览器就会给对应的服务器发送⼀个HTTP请求.对⽅服务器 收到这个请求之后,经过计算处理,就会返回⼀个HTTP响应
事实上,当我们访问⼀个⽹站的时候,可能涉及不⽌⼀次的HTTP请求/响应的交互过程. 可以通过chrome的开发者⼯具观察到这个详细的过程.
通过F12打开chrome的开发者⼯具,切换到Network标签⻚.然后刷新⻚⾯即可看到如下图效果.每 ⼀条记录都是⼀次HTTP请求/响应
注意:当前搜狗主⻚是通过https来进⾏通信的.https是在http基础之上做了⼀个加密解密的⼯作
HTTP协议格式
HTTP是⼀个⽂本格式的协议.可以通过Chrome开发者⼯具或者Fiddler抓包,分析HTTP请求/响应 的细节.
抓包⼯具的使⽤
以Fiddler为例.(下载地址:https://www.telerik.com/fiddler/) 安装过程⽐较简单,⼀路next即可.
• 左侧窗⼝显⽰了所有的HTTP请求/响应,可以选中某个请求查看详情.
• 右侧上⽅显⽰了HTTP请求的报⽂内容.(切换到Raw标签⻚可以看到详细的数据格式)
• 右侧下⽅显⽰了HTTP响应的报⽂内容.(切换到Raw标签⻚可以看到详细的数据格式)
• 请求和响应的详细数据,可以通过右下⻆的 View in Notepad 通过记事本打开. 可以使⽤ctrl+a全选左侧的抓包结果,delete键清除所有被选中的结果
抓包⼯具的原理
Fiddler 相当于⼀个"代理". 浏览器访问sogou.com时,就会把HTTP请求先发给Fiddler,Fiddler再把请求转发给sogou的服务 器.当sogou服务器返回数据时,Fiddler拿到返回数据,再把数据交给浏览器. 因此Fiddler对于浏览器和sogou服务器之间交互的数据细节,都是⾮常清楚的.
代理就可以简单理解为⼀个跑腿⼩弟.你想买罐冰阔落,⼜不想⾃⼰下楼去超市,那么就可以把钱给你 的跑腿⼩弟,跑腿⼩弟来到超市把钱给超市⽼板,再把冰阔落拿回来交到你⼿上.这个过程中,这个跑腿 ⼩弟对于"你"和"超市⽼板"之间的交易细节,是⾮常清楚的
抓包结果
以下是⼀个HTTP请求/响应的抓包结果.
HTTP请求
• ⾸⾏:[⽅法]+[url]+[版本]
• Header:请求的属性,冒号分割的键值对;每组属性之间使⽤\n分隔;遇到空⾏表⽰Header部分结束
• Body:空⾏后⾯的内容都是Body.Body允许为空字符串.如果Body存在,则在Header中会有⼀个 Content-Length属性来标识Body的⻓度;
HTTP响应
• ⾸⾏:[版本号]+[状态码]+[状态码解释]
• Header:请求的属性,冒号分割的键值对;每组属性之间使⽤\n分隔;遇到空⾏表⽰Header部分结束
• Body:空⾏后⾯的内容都是Body.Body允许为空字符串.如果Body存在,则在Header中会有⼀个 Content-Length属性来标识Body的⻓度;如果服务器返回了⼀个html⻚⾯,那么html⻚⾯内容就是 在body中.
协议格式总结
思考问题:为什么HTTP报⽂中要存在"空⾏"?
因为HTTP协议并没有规定报头部分的键值对有多少个.空⾏就相当于是"报头的结束标记",或者是 "报头和正⽂之间的分隔符". HTTP在传输层依赖TCP协议,TCP是⾯向字节流的.如果没有这个空⾏,就会出现"粘包问题".
HTTP请求(Request)
认识URL
URL基本格式
平时我们俗称的"⽹址"其实就是说的URL(UniformResourceLocator统⼀资源定位符).
互联⽹上的每个⽂件都有⼀个唯⼀的URL,它包含的信息指出⽂件的位置以及浏览器应该怎么处理它. URL的详细规则由因特⽹标准RFC1738进⾏了约定.
⼀个具体的URL:
https://v.bitedu.vip/personInf/student?userId=10000&classId=100
可以看到,在这个URL中有些信息被省略了
• https :协议⽅案名.常⻅的有http和https,也有其他的类型.(例如访问mysql时⽤的 jdbc:mysql )
• user:pass :登陆信息.现在的⽹站进⾏⾝份认证⼀般不再通过URL进⾏了.⼀般都会省略
• v .bitedu.vip :服务器地址.此处是⼀个"域名",域名会通过DNS系统解析成⼀个具体的IP地 址.(通过ping命令可以看到, v.bitedu.vip 的真实IP地址为
• 端⼝号:上⾯的URL中端⼝号被省略了.当端⼝号省略的时候,浏览器会根据协议类型⾃动决定使⽤ 哪个端⼝.例如http协议默认使⽤80端⼝,https协议默认使⽤443端⼝.
• / personInf/student :带层次的⽂件路径. 118.24.113.28 )
• userId=10000&classId=100 :查询字符串(querystring).本质是⼀个键值对结构.键值对之 间使⽤&分隔.键和值之间使⽤=分隔.
• ⽚段标识:此URL中省略了⽚段标识.⽚段标识主要⽤于⻚⾯内跳转.(例如Vue官⽅⽂档: https://cn.vuejs.org/v2/guide/#%E8%B5%B7%E6%AD%A5, 通过不同的⽚段标识跳转到⽂档的 不同章节)
使⽤ping命令查看域名对应的IP地址.
1. 在开始菜单中输⼊ cmd ,打开 命令提⽰符
2. 在cmd中输⼊ ping v.bitedu.vip ,即可看到域名解析的结果.
关于querystring
query string 中的内容是键值对结构.其中的key和value的取值和个数,完全都是程序猿⾃⼰约定的.我们可以通过这样的⽅式来⾃定制传输我们需要的信息给服务器
URL中的可省略部分
• 协议名:可以省略,省略后默认为http://
• ip地址/域名:在HTML中可以省略(⽐如img,link,script,a标签的src或者href属性).省略后表 ⽰服务器的ip/域名与当前HTML所属的ip/域名⼀致.
• 端⼝号:可以省略.省略后如果是http协议,端⼝号⾃动设为80;如果是https协议,端⼝号⾃动设为 443.
• 带层次的⽂件路径:可以省略.省略后相当于/.有些服务器会在发现/路径的时候⾃动访问 /index.html
• 查询字符串:可以省略
• ⽚段标识:可以省略
关于URLencode
像/?:等这样的字符,已经被url当做特殊意义理解了.因此这些字符不能随意出现.
⽐如,某个参数中需要带有这些特殊字符,就必须先对特殊字符进⾏转义.
⼀个中⽂字符由UTF-8或者GBK这样的编码⽅式构成,虽然在URL中没有特殊含义,但是仍然需要进 ⾏转义.否则浏览器可能把UTF-8/GBK编码中的某个字节当做URL中的特殊符号. 转义的规则如下:将需要转码的字符转为16进制,然后从右到左,取4位(不⾜4位直接处理),每2位做 ⼀位,前⾯加上%,编码成%XY格式
认识"⽅法"(method)
1. GET⽅法
GET是最常⽤的HTTP⽅法.常⽤于获取服务器上的某个资源.
在浏览器中直接输⼊URL,此时浏览器就会发送出⼀个GET请求.
另外,HTML中的link,img,script等标签,也会触发GET请求.
打开Fiddler,访问搜狗主⻚,观察抓包结果.
在上⾯的结果中可以看到: 最上⾯的
是通过浏览器地址栏发送的GET请求.
下⾯的和sogou域名相关的请求,有些是通过html中的link/script/img标签产⽣的,例如
有些是通过ajax的⽅式产⽣的,例如
选中第⼀条
观察请求的详细结果
GET请求的特点
• ⾸⾏的第⼀部分为GET
• URL的querystring可以为空,也可以不为空
. • header部分有若⼲个键值对结构.
• body部分为空.
2. POST⽅法
POST⽅法也是⼀种常⻅的⽅法.多⽤于提交⽤⼾输⼊的数据给服务器(例如登陆⻚⾯).
通过HTML中的form标签可以构造POST请求,或者使⽤JavaScript的ajax也可以构造POST请求.
使⽤Fiddler观察POST⽅法
在⽐特教务系统的登陆⻚⾯,输⼊⽤⼾名,密码,验证码之后,点击登陆,就可以看到POST请求.
点击这个请求,查看请求详情
POST请求的特点
• ⾸⾏的第⼀部分为POST
• URL的querystring⼀般为空(也可以不为空)
• header部分有若⼲个键值对结构.
• body部分⼀般不为空.body内的数据格式通过header中的 由header中的 Content-Type 指定.body的⻓度 由Content-Length 指定.
经典⾯试题:谈谈GET和POST的区别
• 语义不同:GET⼀般⽤于获取数据,POST⼀般⽤于提交数据.
• GET的body⼀般为空,需要传递的数据通过querystring传递,POST的querystring⼀般为空,需 要传递的数据通过body传递
• GET请求⼀般是幂等的,POST请求⼀般是不幂等的.(如果多次请求得到的结果⼀样,就视为请求是 幂等的).
• GET可以被缓存,POST不能被缓存.(这⼀点也是承接幂等性).
补充说明:
• 关于语义:GET完全可以⽤于提交数据,POST也完全可以⽤于获取数据.
• 关于幂等性:标准建议GET实现为幂等的.实际开发中GET也不必完全遵守这个规则(主流⽹站都有 "猜你喜欢"功能,会根据⽤⼾的历史⾏为实时更新现有的结果
. • 关于安全性:有些资料上说"POST⽐GET请安全".这样的说法是不科学的.是否安全取决于前端在 传输密码等敏感信息时是否进⾏加密,和GETPOST⽆关.
• 关于传输数据量:有的资料上说"GET传输的数据量⼩,POST传输数据量⼤".这个也是不科学的,标 准没有规定GET的URL的⻓度,也没有规定POST的body的⻓度.传输数据量多少,完全取决于不 同浏览器和不同服务器之间的实现区别.
• 关于传输数据类型:有的资料上说"GET只能传输⽂本数据,POST可以传输⼆进制数据".这个也是 不科学的.GET的querystring虽然⽆法直接传输⼆进制数据,但是可以针对⼆进制数据进⾏url encode.
3. 其他⽅法
• PUT与POST相似,只是具有幂等特性,⼀般⽤于更新
• DELETE删除服务器指定资源
• OPTIONS返回服务器所⽀持的请求⽅法
• HEAD类似于GET,只不过响应体不返回,只返回响应头
• TRACE回显服务器端收到的请求,测试的时候会⽤到这个
• CONNECT预留,暂⽆使⽤
这些⽅法的HTTP请求可以使⽤ajax来构造.(也可以通过⼀些第三⽅⼯具) 任何⼀个能进⾏⽹络编程的语⾔都可以构造HTTP请求.本质上就是通过TCPsocket写⼊⼀个符合 HTTP协议规则的字符串.
认识请求"报头"(header)
header 的整体的格式也是"键值对"结构.
每个键值对占⼀⾏.键和值之间使⽤分号分割.
报头的种类有很多,此处仅介绍⼏个常⻅的.
Host 表⽰服务器主机的地址和端⼝.
Content-Length 表⽰body中的数据⻓度.
Content-Type 表⽰请求的body中的数据格式.
常⻅选项:
• application/x-www-form-urlencoded: form 表单提交的数据格式.此时body的格式形如:
title=test&content=hello
multipart/form-data: form 表单提交的数据格式(在form标签中加上 enctyped="multipart/form-data" .通常⽤于提交图⽚/⽂件.body格式形如:
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3Trw
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"
title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png
PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
• application/json: 数据为json格式.body格式形如:
{"username":"123456789","password":"xxxx","code":"jw7l","uuid":"d110a05ccde64b16
User-Agent (简称UA)
表⽰浏览器/操作系统的属性.形如
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
其中 Windows NT 10.0; Win64; x64 表⽰操作系统信息
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77
Safari/537.36 表⽰浏览器信息.
Referer
表⽰这个⻚⾯是从哪个⻚⾯跳转过来的.
形如
https://v.bitedu.vip/login
如果直接在浏览器中输⼊URL,或者直接通过收藏夹访问⻚⾯时是没有Referer的.
理解登陆过程
这个过程和去医院看病很相似.
1. 到了医院先挂号.挂号时候需要提供⾝份证,同时得到了⼀张"就诊卡",这个就诊卡就相当于患者的 "令牌".
2. 后续去各个科室进⾏检查,诊断,开药等操作,都不必再出⽰⾝份证了,只要凭就诊卡即可识别出当前 患者的⾝份.
3. 看完病了之后,不想要就诊卡了,就可以注销这个卡.此时患者的⾝份和就诊卡的关联就销毁了.(类似 于⽹站的注销操作)
4. ⼜来看病,可以办⼀张新的就诊卡,此时就得到了⼀个新的"令牌"
HTTP响应详解
认识"状态码"(statuscode) 状态码表⽰访问⼀个⻚⾯的结果.(是访问成功,还是失败,还是其他的⼀些情况...). 以下为常⻅的状态码.
200OK 这是⼀个最常⻅的状态码,表⽰访问成功.
404NotFound 没有找到资源. 浏览器输⼊⼀个URL,⽬的就是为了访问对⽅服务器上的⼀个资源.如果这个URL标识的资源不存在, 那么就会出现404
405MethodNotAllowed 前⾯我们已经学习了HTTP中所⽀持的⽅法,有GET,POST,PUT,DELETE等. 但是对⽅的服务器不⼀定都⽀持所有的⽅法(或者不允许⽤⼾使⽤⼀些其他的⽅法). . 500Internal Server Error 服务器出现内部错误.⼀般是服务器的代码执⾏过程中遇到了⼀些特殊情况(服务器异常崩溃)会产⽣这 个状态码. 咱们平时常⽤的⽹站很少会出现500(但是偶尔也能看到).
504GatewayTimeout 当服务器负载⽐较⼤的时候,服务器处理单条请求的时候消耗的时间就会很⻓,就可能会导致出现超时 的情况. 这种情况在双⼗⼀等"秒杀"场景中容易出现,平时不太容易⻅到. 302Movetemporarily 临时重定向. 理解"重定向" 就相当于⼿机号码中的"呼叫转移"功能.
⽐如我本来的⼿机号是186-1234-5678,后来换了个新号码135-1234-5678,那么不需要让我的朋友知 道新号码, 只要我去办理⼀个呼叫转移业务,其他⼈拨打186-1234-5678,就会⾃动转移到135-1234-5678上. 在登陆⻚⾯中经常会⻅到302.⽤于实现登陆成功后⾃动跳转到主⻚. 响应报⽂的header部分会包含⼀个Location字段,表⽰要跳转到哪个⻚⾯.
301MovedPermanently 永久重定向.当浏览器收到这种响应时,后续的请求都会被⾃动改成新的地址. 301 也是通过Location字段来表⽰要重定向到的新地址.
状态码⼩结
认识响应"报头"(header)
响应报头的基本格式和请求报头的格式基本⼀致. 类似于 Content-Type , Content-Length 等属性的含义也和请求中的含义⼀致.
Content-Type 响应中的Content-Type常⻅取值有以下⼏种:
• text/html :body数据格式是HTML
• text/css :body数据格式是CSS
• application/javascript :body数据格式是JavaScript
• application/json :body数据格式是JSON
HTTPS
HTTPS是什么
HTTPS也是⼀个应⽤层协议.是在HTTP协议的基础上引⼊了⼀个加密层.
HTTP协议内容都是按照⽂本的⽅式明⽂传输的.这就导致在传输过程中出现⼀些被篡改的情况. 臭名昭著的"运营商劫持"
由于我们通过⽹络传输的任何的数据包都会经过运营商的⽹络设备(路由器,交换机等),那么运营商的⽹ 络设备就可以解析出你传输的数据内容,并进⾏篡改. 点击"下载按钮",其实就是在给服务器发送了⼀个HTTP请求,获取到的HTTP响应其实就包含了该 APP的下载链接.
不⽌运营商可以劫持,其他的⿊客也可以⽤类似的⼿段进⾏劫持,来窃取⽤⼾隐私信息,或者篡改内容. 试想⼀下,如果⿊客在⽤⼾登陆⽀付宝的时候获取到⽤⼾账⼾余额,甚⾄获取到⽤⼾的⽀付密码..... 在互联⽹上,明⽂传输是⽐较危险的事情!!!
HTTPS就是在HTTP的基础上进⾏了加密,进⼀步的来保证⽤⼾的信息安全~
"加密"是什么 加密就是把明⽂(要传输的信息)进⾏⼀系列变换,⽣成密⽂.
解密就是把密⽂再进⾏⼀系列变换,还原成明⽂.
在这个加密和解密的过程中,往往需要⼀个或者多个中间的数据,辅助进⾏这个过程,这样的数据称为密钥,
HTTPS的⼯作过程
既然要保证数据安全,就需要进⾏"加密".
⽹络传输中不再直接传输明⽂了,⽽是加密之后的"密⽂".
加密的⽅式有很多,但是整体可以分成两⼤类:对称加密和⾮对称加密
引⼊对称加密
对称加密其实就是通过同⼀个"密钥",把明⽂加密成密⽂,并且也能把密⽂解密成明⽂.
⼀个简单的对称加密,按位异或
假设明⽂a=1234,密钥key=8888
则加密a^key得到的密⽂b为9834.
然后针对密⽂9834再次进⾏运算b^key,得到的就是原来的明⽂1234.
(对于字符串的对称加密也是同理,每⼀个字符都可以表⽰成⼀个数字)
当然,按位异或只是最简单的对称加密.HTTPS中并不是使⽤按位异或
引⼊对称加密之后,即使数据被截获,由于⿊客不知道密钥是啥,因此就⽆法进⾏解密,也就不知道请求 的真实内容是啥了.
但事情没这么简单.服务器同⼀时刻其实是给很多客⼾端提供服务的.这么多客⼾端,每个⼈⽤的秘钥都 必须是不同的(如果是相同那密钥就太容易扩散了,⿊客就也能拿到了).因此服务器就需要维护每个客⼾ 端和每个密钥之间的关联关系,这也是个很⿇烦的事情~
⽐较理想的做法,就是能在客⼾端和服务器建⽴连接的时候,双⽅协商确定这次的密钥是啥~
但是如果直接把密钥明⽂传输,那么⿊客也就能获得密钥了~~此时后续的加密操作就形同虚设了. **因此密钥的传输也必须加密传输!**
但是要想对密钥进⾏对称加密,就仍然需要先协商确定⼀个"密钥的密钥".这就成了"先有鸡还是先有 蛋"的问题了.此时密钥的传输再⽤对称加密就⾏不通了. 就需要引⼊⾮对称加密.
引⼊⾮对称加密
⾮对称加密要⽤到两个密钥,⼀个叫做"公钥",⼀个叫做"私钥".
公钥和私钥是配对的.最⼤的缺点就是运算速度⾮常慢,⽐对称加密要慢很多.
• 通过公钥对明⽂加密,变成密⽂
• 通过私钥对密⽂解密,变成明⽂ 也可以反着⽤
• 通过私钥对明⽂加密,变成密⽂
• 通过公钥对密⽂解密,变成明⽂
⾮对称加密的数学原理⽐较复杂,涉及到⼀些数论相关的知识.这⾥举⼀个简单的⽣活上的例⼦.
A要给B⼀些重要的⽂件,但是B可能不在.于是A和B提前做出约定: B说:我桌⼦上有个盒⼦,然后我给你⼀把锁,你把⽂件放盒⼦⾥⽤锁锁上,然后我回头拿着钥匙来开锁 取⽂件.
在这个场景中,这把锁就相当于公钥,钥匙就是私钥.公钥给谁都⾏(不怕泄露),但是私钥只有B⾃⼰持 有.持有私钥的⼈才能解密.
• 客⼾端在本地⽣成对称密钥,通过公钥加密,发送给服务器.
• 由于中间的⽹络设备没有私钥,即使截获了数据,也⽆法还原出内部的原⽂,也就⽆法获取到对称密 钥
• 服务器通过私钥解密,还原出客⼾端发送的对称密钥.并且使⽤这个对称密钥加密给客⼾端返回的响 应数据.
• 后续客⼾端和服务器的通信都只⽤对称加密即可.由于该密钥只有客⼾端和服务器两个主机知道,其他主机/设备不知道密钥即使截获数据也没有意义. 由于对称加密的效率⽐⾮对称加密⾼很多,因此只是在开始阶段协商密钥的时候使⽤⾮对称加密,后续 的传输仍然使⽤对称加密.
那么接下来问题⼜来了:
• 客⼾端如何获取到公钥?
• 客⼾端如何确定这个公钥不是⿊客伪造的?
中间⼈攻击
⿊客可以使⽤中间⼈攻击,获取到对称密钥
1. 服务器具有⾮对称加密算法的公钥S,私钥S'
2. 中间⼈具有⾮对称加密算法的公钥M,私钥M'
3. 客⼾端向服务器发起请求,服务器明⽂传送公钥S给客⼾端
4. 中间⼈劫持数据报⽂,提取公钥S并保存好,然后将被劫持报⽂中的公钥S替换成为⾃⼰的公钥M, 并将伪造报⽂发给客⼾端
5. 客⼾端收到报⽂,提取公钥M(⾃⼰当然不知道公钥被更换过了),⾃⼰形成对称秘钥X,⽤公钥M加密X,形成报⽂发送给服务器
6. 中间⼈劫持后,直接⽤⾃⼰的私钥M'进⾏解密,得到通信秘钥X,再⽤曾经保存的服务端公钥S加密后,将报⽂推送给服务器
7. 服务器拿到报⽂,⽤⾃⼰的私钥S'解密,得到通信秘钥X
8. 双⽅开始采⽤X进⾏对称加密,进⾏通信。但是⼀切都在中间⼈的掌握中,劫持数据,进⾏窃听甚⾄修改,都是可以的
引⼊证书
服务端在使⽤HTTPS前,需要向CA机构申领⼀份数字证书,数字证书⾥含有证书申请者信息、公钥信 息等。服务器把证书传输给浏览器,浏览器从证书⾥获取公钥就⾏了,证书就如⾝份证,证明服务端 公钥的权威性
这个证书可以理解成是⼀个结构化的字符串,⾥⾯包含了以下信息:
• 证书发布机构
• 证书有效期
• 公钥
• 证书所有者
• 签名
• ......
需要注意的是:申请证书的时候,需要在特定平台⽣成查,会同时⽣成⼀对⼉密钥对⼉,即公钥和私 钥。这对密钥对⼉就是⽤来在⽹络通信中进⾏明⽂加密以及数字签名的。
理解数据签名
签名的形成是基于⾮对称加密算法的,注意,⽬前暂时和https没有关系,不要和https中的公钥私钥搞 混了
当服务端申请CA证书的时候,CA机构会对该服务端进⾏审核,并专⻔为该⽹站形成数字签名,过程如 下:
1. CA机构拥有⾮对称加密的私钥A和公钥A'
2. CA机构对服务端申请的证书明⽂数据进⾏hash,形成数据摘要
3. 然后对数据摘要⽤CA私钥A'加密,得到数字签名S
服务端申请的证书明⽂和数字签名S共同组成了数字证书,这样⼀份数字证书就可以颁发给服务端了
通过证书解决中间⼈攻击
在客⼾端和服务器刚⼀建⽴连接的时候,服务器给客⼾端返回⼀个证书. 这个证书包含了刚才的公钥,也包含了⽹站的⾝份信息
当客⼾端获取到这个证书之后,会对证书进⾏校验(防⽌证书是伪造的).
• 判定证书的有效期是否过期
• 判定证书的发布机构是否受信任(操作系统中已内置的受信任的证书发布机构).
• 验证证书是否被篡改:从系统中拿到该证书发布机构的公钥,对签名解密,得到⼀个hash值(称为数 据摘要),设为hash1.然后计算整个证书的hash值,设为hash2.对⽐hash1和hash2是否相等.如 果相等,则说明证书是没有被篡改过的.
中间⼈有没有可能篡改该证书?
• 中间⼈篡改了证书的明⽂
• 由于他没有CA机构的私钥,所以⽆法hash之后⽤私钥加密形成签名,那么也就没法办法对篡改后 的证书形成匹配的签名
• 如果强⾏篡改,客⼾端收到该证书后会发现明⽂和签名解密后的值不⼀致,则说明证书已被篡改, 证书不可信,从⽽终⽌向服务器传输信息,防⽌信息泄露给中间⼈
中间⼈整个掉包证书?
• 因为中间⼈没有CA私钥,所以⽆法制作假的证书(为什么?)
• 所以中间⼈只能向CA申请真证书,然后⽤⾃⼰申请的证书进⾏掉包
• 这个确实能做到证书的整体掉包,但是别忘记,证书明⽂中包含了域名等服务端认证信息,如果整 体掉包,客⼾端依旧能够识别出来。
• 永远记住:中间⼈没有CA私钥,所以对任何证书都⽆法进⾏合法修改,包括⾃⼰的
为什么签名不直接加密,⽽是要先hash形成摘要?
• 缩⼩签名密⽂的⻓度,加快数字签名的验证签名的运算速度