目录
一.HTTP协议
1.什么是HTTP
2.HTTP发展历史
3.HTTP请求和响应
4. 抓包的方式和工具Fiddler
1.开发者工具
2.Fiddler
二.请求和响应
1.请求和响应报文
2.URL结构
3.常见的方法
1.GET方法
2.POST方法
3.其他方法
三.请求报头(header)
1.Host
2.Content-Length
3.Content-Type
4.User-Agent(UA)
5.Referer
6.Cookie
四.响应详解(Response)
1.常见的状态码
1.200 OK
2.响应 "报头" (header)
五.发送POST和GET请求
1.通过form表单构建HTTP 请求
1.GET
2.POST
2.通过ajax构建HTTP 请求
1.GET
2.POST
六.HTTPS
1.什么是HTTPS
2.SSL/TLS协议
3.为什么会出现HTTPS
4.加密和常见的加密方式
1.对称加密
2.非对称加密
3.哈希函数
5.什么是证书
6.HTTPS的工作流程
1.引入对称加密
2.引入非对称加密
3.引入证书
4.完整流程
一.HTTP协议
1.什么是HTTP
超文本的解释:所谓超文本指的是传输的内容不止是文本内容(html,css),还可能是一些其它资源,如音频,图片,视频等
HTTP是基于TCP协议的一种应用层协议,无论是哪个应用实现实现(不一定非要浏览器),只要按协议规定的格式完成数据的编码与解析
编码完成后通过socket api发送出去,接收到数据之后再按规定的格式去解析就可以了
常见的应用场景:
- 浏览器和服务器之间通信
- 手机与服务器之间通信
- 多个服务器之间进行调用(请求转发)
2.HTTP发展历史
3.HTTP请求和响应
当我们在浏览器中输入URL(例如www.baidu.com),根据域名通过DNS解析成ip地址,给TCP/IP发送给服务器HTTP请求(request),服务器接收到请求之后,分析用户需要访问哪些资源,然后将所需的资源响应(response)给浏览器,浏览器解析响应的数据,渲染到页面上.
当发送请求和接收响应的时候,我们该如何查看请求的具体信息和响应的具体信息呢?
4. 抓包的方式和工具Fiddler
1.开发者工具
无论在哪一个浏览器,我们按键盘上的F12(可以按Fn+Esc开启FnLock)的时候,就可以打开开发者工具,里面的Network(或者网络)就是访问网站的具体请求和响应信息
FireFox访问百度页面
Google Chrome访问百度页面
2.Fiddler
可以通过官网Fiddler来进行下载抓包工具,下载Fiddler Classic版本即可
请求报文的信息在记事本查看
Fiddler工作原理
当浏览器发送请求到服务器的时候,Fiddler在浏览器发送请求之后先拿到请求,然后Fiddler再把请求发送给服务器,服务器发送响应的时候,Fiddler先接受到响应,然后再将响应发送给浏览器.
二.请求和响应
1.请求和响应报文
下面是具体的请求和响应报文的大致结构
2.URL结构
URL:(Uniform Resource Locator 统一资源定位符)
URI:(Uniform Resource Identifier 统一资源标识符),一般在使用时候理解为同一个意思
下面是一个常见的URL地址
- https : 协议方案名. 常见的有 http 和 https, 也有其他的类型. (例如访问 mysql 时用的 jdbc:mysql )
- user:pass : 登陆信息. 现在的网站进行身份认证一般不再通过 URL 进行了. 一般都会省略
- www.javacn.site: 服务器地址. 此处是一个 "域名", 域名会通过 DNS 系统解析成一个具体的 IP 地址. (通过 ping 命令可以看到, www.javacn.site 的真实 IP 地址为 82.157.146.10) 可直接访问上面的网站
- 端口号: 上面的 URL 中端口号被省略了. 当端口号省略的时候, 浏览器会根据协议类型自动决定使用哪个端口. 例如 http 协议默认使用 80 端口, https 协议默认使用 443 端口.
- /interview/net/tcpip.html: 带层次的文件路径.
- userId=10000&classId=100 : 查询字符串(query string). 本质是一个键值对结构. 键值对之间使 用 & 分隔. 键和值之间使用 = 分隔.
- 片段标识: 此 URL 中省略了片段标识. 片段标识主要用于页面内跳转.
比如一篇文章的内容很长,用片段标识就可以很容易的定位到文章的某一个位置
?后面跟着查询字符串,也是以键值对的形式来表示的,key=value如果有多个键值对要用&分隔
key=value&key1=value1&key2=value2
3.常见的方法
请求的首行为:请求的方法,请求的地址,版本号
1.GET方法
1.如何发送一个GET请求
- 直接从浏览器输入URL地址,浏览器就会默认发送一个GET请求
- 通过form表单指定提交的方法为GET
- 通过AJAX方式发送一个GET请求
- HTML中的link,img,script等标签,也会触发GET请求.
2.GET请求的特点
- 首行的第一部分为GET
- URL的query string可以为空,也可以不为空
- header部分有若干个键值对结构.
- body部分为空.
关于 GET 请求的 URL 长度问题网上有些资料上描述 : get 请求长度最多 1024kb 这样的说法是错误的 .HTTP 协议由 RFC 2616 标准定义 , 标准原文中明确说明 : "Hypertext Transfer Protocol --HTTP/1.1," does not specify any requirement for URL length.没有对 URL 的长度有任何的限制 .实际 URL 的长度取决于浏览器的实现和 HTTP 服务器端的实现 . 在浏览器端 , 不同的浏览器最大长度是不同的 , 但是现代浏览器支持的长度一般都很长 ; 在服务器端 , 一般这个长度是可以配置的 .
2.POST方法
1.如何发送一个POST请求
- 通过form表单method=post
- AJAX方式指定method=post;
2.POST请求的特点
通过gitee进行登录操作的post请求
- 首行的第一部分为 POST
- URL 的 query string 一般为空 (也可以不为空)
- header 部分有若干个键值对结构.
- body 部分一般不为空. body 内的数据格式通过 header 中的 Content-Type 指定. body 的长度由 header 中的 Content-Length 指定.
header和body之间空行的作用,为了解决粘包问题
面试题:谈谈GET和POST的区别
- 首先从总体上说,GET和POST本质上没有本质区别,两种方法都可以相互代替
- 语义不同:GET一般用于获取数据,POST一般用于提交数据.
- 使用习惯: GET的body一般为空,需要传递的数据通过query string 传递, POST的query string一般为空,需要传递的数据通过body传递
- GET请求一般是幂等的, POST请求一般是不幂等的.(如果多次请求得到的结果一样,就视为请求是幂等的)
- GET可以被缓存,POST不能被缓存.(因为GET请求是幂等的(得到的结果是一样的),因此进行缓存更加节省带宽资源,加快访问速度)
3.其他方法
- PUT 与 POST 相似,只是具有幂等特性,一般用于更新
- DELETE 删除服务器指定资源
- OPTIONS 返回服务器所支持的请求方法
- HEAD 类似于GET,只不过响应体不返回,只返回响应头
- TRACE 回显服务器端收到的请求,测试的时候会用到这个
- CONNECT 预留,暂无使用
三.请求报头(header)
1.Host
表示服务器的主机地址和端口
域名最终会被DNS服务器解析为IP地址,端口号确定与服务器对应的进程
2.Content-Length
表示 body中的数据长度
可以根据长度判断报文终止位置,一般不用我们手动指定,浏览器和服务器自己会计算好并赋值
如上面表示的body的长度为469个字节
3.Content-Type
4.User-Agent(UA)
表示浏览器/操作系统的属性
使用UA可以让服务器收集客户端的环境,或是浏览器/操作系统的环境.
可以根据用户的浏览器和系统版,返回适合于当前用户的页面老的浏览器或系统,返回一些功能少的适合于老系统的页面,反之,比较新的浏览器或系统,就返回功能比较新的页面
5.Referer
记录是从哪一个URL跳转到当前页面的.
这个表示从gitee主页跳转到我本人的主页. .
实际案例:商城向其他平台投放广告,通过Referer信息来统计用户是从哪些平台点击进入到商城的,这样可以确定之后在哪个平台投放广告的效益最高.
6.Cookie
一个场景:
我们知道当我们访问网站(登录校验)的时候都需要进行用户的登录,当我们第一次登录了之后,我们可以访问响应的网站,但此时我们需要访问此站点的另一个网站,此时也是需要进行登录校验的,这个时候如果还是用户发送登录请求,这样用户的体验是很差的,因为刚才已经登录过了.那么我们该如何解决这个问题呢?接下来Cookie登场.
登录案例进行举例:
当我们第一次进行登录的时候,客户端发送请求,将登录的账号和密码发送给服务端,服务端进行账号和密码的验证,如果正确,登陆成功,此时会发送一个登录成功的响应
第一次登录的响应信息
HTTP/1.1 302 FoundDate: Thu, 10 Jun 2021 04:15:58 GMTContent-Type: text/html; charset=utf-8Connection: keep-aliveKeep-Alive: timeout=60Server: nginxX-XSS-Protection: 1; mode=blockX-Content-Type-Options: nosniffX-UA-Compatible: chrome=1Expires: Sun, 1 Jan 2000 01:00:00 GMTPragma: must-revalidate, no-cache, privateLocation: https://gitee.com/HGtz2222Cache-Control: no-cacheSet-Cookie: oschina_new_user=false; path=/; expires=Mon, 10 Jun 2041 04:16:00-0000Set-Cookie: gitee_user=true; path=/Set-Cookie: gitee-sessionn=M1Rhbk1QUUxQdWk1VEZVQ1BvZXYybG13ZUJFNGR1V0pSYTZyTllEa21pVHlBUE5QU2Qwdk44NXdEam11T3FZYXFidGNYaFJxcTVDRE1xU05GUXN0ek1Uc08reXRTay9ueTV3OGl5bTdzVGJjU1lUbTJ4bTUvN1l3RFl4N2hNQmI1SEZpdmVJWStETlJrdWtyU0lDckhvSGJHc3NEZDFWdHc5cjdHaGVtNThNcEVOeFZlaHc0WVY5NGUzWjc2cjdOcCtSdVJ0VndzdVNxb3dHK1hPSDBDSFB6WlZDc3prUVZ2RVJyTnpTb1c4aFg1MmUxM1YvQTFkb1EwaU4zT3hJcmRrS3dxVFZJNXoxaVJwa1liMlplbWR5QXQxY0lvUDNic1hxN2o0WDg1WkE9LS10N0VIYXg4Vm5xdllHVzdxa0VlUEp3PT0%3D--2f6a24f8d33929fe88ed19d4dea495fbb40ebed6; domain=.gitee.com; path=/; HttpOnlyX-Request-Id: 77f12d095edc98fab27d040a861f63b1X-Runtime: 0.166621Content-Length: 92
可以看到响应中的set-cookie方法,在客户端中进行了cookie的设置,此后每一次向服务端发送请求的时候,都会将cookie放在请求头中发送出去,这样服务端进行cookie的校验,如果合理就不需要重新登录(表示之前已经登录过了),然后将相应的响应传送给前端
访问其他网站的请求信息
GET https://gitee.com/HGtz2222 HTTP/1.1Host: gitee.comConnection: keep-aliveCache-Control: max-age=0Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/91.0.4472.101 Safari/537.36Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Sec-Fetch-Site: same-originSec-Fetch-Mode: navigateSec-Fetch-User: ?1Sec-Fetch-Dest: documentsec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"sec-ch-ua-mobile: ?0Referer: https://gitee.com/loginAccept-Encoding: gzip, deflate, brAccept-Language: zh-CN,zh;q=0.9,en;q=0.8Cookie: oschina_new_user=false; user_locale=zh-CN; yp_riddler_id=1ce4a551-a160-4358-aa73-472762c79dc0; visit-gitee--2021-05-06%2010%3A12%3A24%20%2B0800=1;sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%22726826%22%2C%22first_id%22%3A%22175869ba5888b6-0ea2311dc53295-303464-2073600-175869ba5899ac%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22%24device_id%22%3A%22175869ba5888b6-0ea2311dc53295-303464-2073600-175869ba5899ac%22%7D; remote_way=svn;tz=Asia%2FShanghai;Hm_lvt_24f17767262929947cc3631f99bfd274=1622637014,1622712683,1622863899,1623298442; Hm_lpvt_24f17767262929947cc3631f99bfd274=1623298550; gitee_user=true;gitee-sessionn=M1Rhbk1QUUxQdWk1VEZVQ1BvZXYybG13ZUJFNGR1V0pSYTZyTllEa21pVHlBUE5QU2Qwdk44NXdEam11T3FZYXFidGNYaFJxcTVDRE1xU05GUXN0ek1Uc08reXRTay9ueTV3OGl5bTdzVGJjU1lUbTJ4bTUvN1l3RFl4N2hNQmI1SEZpdmVJWStETlJrdWtyU0lDckhvSGJHc3NEZDFWdHc5cjdHaGVtNThNcEVOeFZlaHc0WVY5NGUzWjc2cjdOcCtSdVJ0VndzdVNxb3dHK1hPSDBDSFB6WlZDc3prUVZ2RVJyTnpTb1c4aFg1MmUxM1YvQTFkb1EwaU4zT3hJcmRrS3dxVFZJNXoxaVJwa1liMlplbWR5QXQxY0lvUDNic1hxN2o0WDg1WkE9LS10N0VIYXg4Vm5xdllHVzdxa0VlUEp3PT0%3D--2f6a24f8d33929f e88ed19d4dea495fbb40ebed6
请求体中的内容由请求头中的Content-Type和Content-Length决定,具体在Content-Type有展示请求体的内容
四.响应详解(Response)
HTTP/1.1 200 OK
Server: nginx
Date: Fri, 16 Jun 2023 02:39:52 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Set-Cookie: black_passportid=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; domain=.sogou.com
Pragma: No-cache
Cache-Control: max-age=0
Expires: Fri, 16 Jun 2023 02:39:52 GMT
UUID: 15d42449-0c66-4731-8e40-72ff80e09202
Content-Encoding: gzip
1.常见的状态码
1.200 OK
表示访问成功
注意:在抓包的时候看到请求体被压缩的数据
进行解压操作,下面就是解压后面的数据
2.403 Forbidden
服务器上的资源是存在的,但是没有授权给当前用户也就是说当前用户无权访问,返回403状态码
3.404 Not Found
表示没有找到资源. 这也是我们开发中常见的问题,一般是URL写错了
4.405 Method Not Allowed
客户端如果发送GET请求到服务器
服务器必然会有一个接收GET请求的方法来处理这个请求
客户端如果发送POST请求到服务器
服务器必须也会有一个接收POST请求的方法来处理这个POST请求
如果我们发送了一个post请求服务器,但是服务器没有处理post请求的方法,此时就会报405错误
5.500 Internal Server Error
6.504 Gateway Timeout
7.301 Moved Permanently
表示永久重定向.
理解 " 重定向 "就相当于手机号码中的 " 呼叫转移 " 功能 .比如我本来的手机号是 186-1234-5678, 后来换了个新号码 135-1234-5678, 那么不需要让我的朋友知道新号码 ,只要我去办理一个呼叫转移业务 , 其他人拨打 186-1234-5678 , 就会自动转移到 135-1234-5678上 .
常的场景是,老域名不用了,当前户访问老域名的时候强制跳转到新的域名下
Location字段表示要跳转的页面
8.302 Move temporarily
表示临时重定向.
这种重定向是临时的,可能之后不需要重定向需要了.
2.响应 "报头" (header)
1.Content-Type
响应中的Content-Type常见取值有以下几种:
- text/html: body数据格式是HTML
- text/css: body数据格式是CSS
- application/javascript: body数据格式是JavaScript
- application/json: body数据格式是JSON
五.发送POST和GET请求
1.通过form表单构建HTTP 请求
form表单的重要参数
- action: 构造的 HTTP 请求的 URL 是什么.
- method: 构造的 HTTP 请求的方法是 GET 还是 POST (form 只支持 GET 和 POST).
1.GET
<body>
<form method="get" action="calc">
<div style="margin-top: 50px; margin-left: 50px;">
<h1>计算器--add</h1>
num1:<input name="num1"><br>
num2:<input name="num2"><br>
<input type="submit" value="相加"><br>
</div>
</form>
</body>
页面效果
在文本框中输入值就可以点击相加按钮就可以按照method的方式提交到指定的action中.
get方式提交的请求我们可以看到num1和num2拼接到query string中进行传输
2.POST
<body>
<form method="post" action="calc">
<div style="margin-top: 50px; margin-left: 50px;">
<h1>计算器--add</h1>
num1:<input name="num1"><br>
num2:<input name="num2"><br>
<input type="submit" value="相加"><br>
</div>
</form>
</body>
post请求进行提交的,数据以application/x-www-form-urlencoded的格式存储在请求体(body)中
POST http://localhost:63342/Data%20Structure%20and%20Algorithm/Servlet-demo1/src/main/webapp/calc HTTP/1.1
Host: localhost:63342
Connection: keep-alive
Content-Length: 15
Cache-Control: max-age=0
sec-ch-ua: "Not.A/Brand";v="8", "Chromium";v="114", "Google Chrome";v="114"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
Origin: http://localhost:63342
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: http://localhost:63342/Data%20Structure%20and%20Algorithm/Servlet-demo1/src/main/webapp/calc.html?_ijt=o10fgu7m56l1b7gr29mv0mfcmh&_ij_reload=RELOAD_ON_SAVE
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: Idea-1c60499a=fb667c55-de72-45c7-b097-0117c2af38f3num1=12&num2=13
2.通过ajax构建HTTP 请求
ajax的最大优点:传统的form表单提交会造成页面的跳转,ajax不会造成跳转,局部更新
实现ajax方式:①XMLHttpRequest内置实现(繁琐,不做讲解)②jQuery对常用操作进行了封装(重点)
引入jquery
我们可以自行在网上下载一个的包,放在工程下面即可,推荐系在jquery.min.js,这个包更加的小,容易节省资源,使用起来的效果和非min版的一样.
接下来就可以在head中的script标签中引入放入的jquery.
1.GET
第一种方法
jQuery.get(url,callback),第一个参数是提交的url,第二个参数是回调函数(不推荐)
jQuery.get("calc_ajax",function (res){
alert(res.data+" "+res.code);
})
第二种方法(推荐)
//发送Ajax请求到后端
jQuery.ajax({
url: "calc_ajax", //提交的地址
method: "GET", //请求的类型
data: {
"num1": num1.val(),
"num2": num2.val()
},
success: function (res) {
if (res.code == 200) {
alert("计算的结果为:"+res.data);
} else {
alert("操作失败" + res.msg);
}
}
});
发送ajax请求信息: 数据拼接在query string中
GET http://localhost:8080/Servlet_demo1_war/calc_ajax?num1=12&num2=13 HTTP/1.1
Host: localhost:8080
Connection: keep-alive
sec-ch-ua: "Not.A/Brand";v="8", "Chromium";v="114", "Google Chrome";v="114"
Accept: */*
X-Requested-With: XMLHttpRequest
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
sec-ch-ua-platform: "Windows"
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost:8080/Servlet_demo1_war/calc-ajax.html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: Idea-1c60499a=fb667c55-de72-45c7-b097-0117c2af38f3
2.POST
第一种方法
jQuery.get(url,data,callback),第一个参数是提交的url,第二个为提交的参数,第三个参数是回调函数
jQuery.post("calc_ajax",{
id:10,
name:"张选宁"
},
function (res){
alert(res.data+" "+res.code);
});
第二种方法(推荐)
//发送Ajax请求到后端
jQuery.ajax({
url: "calc_ajax", //提交的地址
method: "POST", //请求的类型
data: {
"num1": num1.val(),
"num2": num2.val()
},
success: function (res) {
if (res.code == 200) {
alert("计算的结果为:"+res.data);
} else {
alert("操作失败" + res.msg);
}
}
});
发送ajax请求信息: 数据在请求体(body)中
POST http://localhost:8080/Servlet_demo1_war/calc_ajax HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 15
sec-ch-ua: "Not.A/Brand";v="8", "Chromium";v="114", "Google Chrome";v="114"
Accept: */*
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
sec-ch-ua-platform: "Windows"
Origin: http://localhost:8080
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost:8080/Servlet_demo1_war/calc-ajax.html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Cookie: Idea-1c60499a=fb667c55-de72-45c7-b097-0117c2af38f3num1=15&num2=16
六.HTTPS
1.什么是HTTPS
HTTPS(Hyper Text Transfer Protocol Secure,安全的超文本传输协议)是一种基于 SSL/TLS 协议的 HTTP 协议,它是 HTTP 协议的安全版本。HTTPS 协议通过加密通信内容和身份验证来保证数据传输的安全性和完整性,从而可以有效地防止数据在传输过程中被窃取或篡改。
HTTP的默认端口号为80,HTTPS的默认端口号为443
HTTPS = HTTP + 加密 + 认证 + 完整性保护。
2.SSL/TLS协议
SSL(Secure Socket Layer):安全套节层协议。 TLS(Transport Layer Security):传输层安全协议。 SSL(Secure Socket Layer)最早是由浏览器开发厂商网景公司开发的,此公司开发了 SSL 3.0 及 3.0 之前的版本,之后便将 SSL 交给了 IETF(Internet Engineering Task Force)Internet 工程任务组的手中,IETF 以 SSL 3.0 为基础开发了 TLS 1.0,所以可以认为 TLS 是 SSL 的“新版本”。
IETF:互联网工程任务组,致力于互联网标准的制定和推广,是互联网标准化方面的权威组织之一.
3.为什么会出现HTTPS
当我们在网络上传送数据的时候,如果我们不对数据进行加密,比如进行登录的时候,我们将账号和密码放在响应体中明文进行传输,这样一些黑客用抓包工具等手段可以劫持我们的请求信息,从而拿到我们的信息,或者拿到服务端响应给客户端的token信息,这样黑客就可以很容易的劫持到我们的个人信息,很不安全,因此我们就需要对我们在网络中传输的数据进行加密,从而不这么容易让黑客进行获取.HTTPS 就是在 HTTP 的基础上进行了加密, 进一步的来保证用户的信息安全~
4.加密和常见的加密方式
具体例子:比如我们对数字5进行传输,我们的 加密方式是将明文加上密钥,解密方式是将密文减去密钥明文:5加密之后:9解密之后:5密钥:4
1.对称加密
使用相同的密钥进行加密和解密的算法。发送方和接收方必须共享密钥才能进行通信,这使得对称加密算法在保密性和性能方面非常高效。常见的对称加密算法包括 AES(高级加密标准)和 DES(数据加密标准)
2.非对称加密
也称为公钥加密,使用一对密钥,即公钥和私钥。发送方使用接收方的公钥进行加密,而接收方使用其私钥进行解密(也可以使用私钥进行加密,公钥进行解密)。非对称加密算法可以实现加密和数字签名等功能。保密性很好,性能与对称加密对比相对比较低,常见的非对称加密算法包括 RSA 和 ECC(椭圆曲线加密).
3.哈希函数
称为散列函数,将任意长度的输入数据映射为固定长度的输出值(哈希值)。哈希函数通常用于验证数据的完整性,常见的哈希函数包括 MD5、SHA-1、SHA-256 等。哈希函数是不可逆的,即无法从哈希值还原出原始输入,但是可以对比两个数据是否相同,将一个数据加密保存,另一个数据进行加密对比.
- 定长: 无论多长的字符串, 计算出来的 MD5 值都是固定长度 (16字节版本或者32字节版本)
- 分散: 源字符串只要改变一点点, 最终得到的 MD5 值都会差别很大.
- 不可逆: 通过源字符串生成 MD5 很容易, 但是通过 MD5 还原成原串理论上是不可能的.
5.什么是证书
下面是证书的基本信息
下面详细信息
6.HTTPS的工作流程
问题1:明文传送数据会让黑客获取到传输的信息.
1.引入对称加密
但是现在出现一个问题.服务器和客户端进行对称加密的使用需要使用的是一把密钥,这样才能同时对数据进行加密和解密.如果两者需要使用同样的密钥,一定要涉及到密钥传输的过程,也就是密钥需要由客户端传输给服务端(或者服务端传输给客户端),在密钥传输的过程中可能黑客会获取到密钥,对数据进行解密从而获取到信息,这样也是不安全的.
因此密钥的传输也需要进行加密,但此时不能使用对称加密了,如果这样的话就变成一个死循环的问题了(重复处理上面的问题).此时我们引入了非对称加密.
2.引入非对称加密
- 客户端在本地生成对称密钥, 通过公钥给对称密钥进行加密, 发送给服务器.
- 由于中间的网络设备没有私钥, 即使截获了数据, 也无法还原出内部的原文, 也就无法获取到对称密钥
- 服务器通过私钥解密, 还原出客户端发送的对称密钥. 并且使用这个对称密钥加密给客户端返回的响应数据.
- 后续客户端和服务器的通信都只用对称加密即可. 由于该密钥只有客户端和服务器两个主机知道, 其他主机/设备不知道密钥即使截获数据也没有意义.
由于对称加密的效率比非对称加密高很多, 因此只是在开始阶段协商密钥的时候使用非对称加密,
后续的传输仍然使用对称加密.
3.引入证书
在客户端和服务器刚一建立连接的时候, 服务器给客户端返回一个 证书.
这个证书包含了刚才的公钥(解决了问题一), 也包含了网站的身份信息.
当客户端获取到这个证书之后, 会对证书进行校验(防止证书是伪造的).
- 判定证书的有效期是否过期
- 判定证书的发布机构是否受信任(操作系统中已内置的受信任的证书发布机构).
- 验证证书是否被篡改: 从系统中拿到该证书发布机构的公钥, 对签名解密, 得到一个 hash 值(称为数据摘要), 设为 hash1. 然后计算整个证书的 hash 值, 设为 hash2. 对比 hash1 和 hash2 是否相等.
- 如果相等, 则说明证书是没有被篡改过的. (解决了问题二)
理解数据摘要 / 签名
以后我们参加工作后, 经常会涉及到 "报销" 的场景. 你拿着发票想报销, 需要领导批准. 但是领导又不能和你一起去找财务. 那咋办?
很简单, 领导给你签个字就行了. 财务见到领导的签字, "见字如见人".
因为不同的人, "签名" 的差别会很大. 使用签名就可以一定程度的区分某个特定的人.
类似的, 针对一段数据(比如一个字符串), 也可以通过一些特定的算法, 对这个字符串生成一个 "签名". 并保证不同的数据, 生成的 "签名" 差别很大. 这样使用这样的签名就可以一定程度的区分不同的数据.
常见的生成签名的算法有: MD5 和 SHA 系列
以 MD5 为例, 我们不需要研究具体的计算签名的过程, 只需要了解 MD5 的特点:
- 定长: 无论多长的字符串, 计算出来的 MD5 值都是固定长度 (16字节版本或者32字节版本)
- 分散: 源字符串只要改变一点点, 最终得到的 MD5 值都会差别很大.
- 不可逆: 通过源字符串生成 MD5 很容易, 但是通过 MD5 还原成原串理论上是不可能的.
正因为 MD5 有这样的特性, 我们可以认为如果两个字符串的 MD5 值相同, 则认为这两个字符串相同.
服务器阶段对证书的内容生成MD5值作为签名,然后在客户端接收到证书的时候,对此时证书的内容生成MD5,对比签名与此时生成的MD5值是否一致,如果不一致,说明证书的内容被篡改过.如果一致,说明证书内容和服务器端的一致(传输的过程中没有被篡改过),此时就可以放心的使用证书里面的公钥进行后续的操作了.
但是可能会出现这种情况,黑客拿到证书之后,对证书的内容进行了修改,并且对签名的内容重新计算了MD5取代了作为签名,客户端进行证书验证的时候就无法检测出证书是否被修改过. 这个时候就会出现问题了.此时该如何解决?
所以被传输的签名就不能明文进行传输,也需要密文传输,而且不能使用对称加密,否则又会出现上述出现的问题,因此我们是采用非对称加密,那么此时的公钥和私钥如何获取呢?
首先私钥只能服务端从CA机构注册证书的时候进行获取,私钥是不包含在证书之中进行传输的,因此服务器端先用私钥对签名进行加密处理,然后传输给客户端(就算黑客获取到了证书,从CA机构获取到公钥,那么他对签名进行解密并修改,此时黑客无法对签名重新进行加密,客户端就能检测出证书已经被篡改了).传输到客户端的时候,客户端从CA机构获取到公钥对签名进行解密,并计算证书的MD5值与解密后的签名进行对比,检查证书是否被修改过.
这样我们就解决了所有的问题.下面是完整的流程.
4.完整流程
首先客户端内置了CA证书的公钥1,服务端向CA机构申请了证书和并获取到了私钥1,然后服务器端生成了公钥2和私钥2.客户端发送建立连接的请求,TCP三次握手建立了连接.然后服务器端将公钥2放到了证书中,并对证书内容用哈希函数(如MD5)计算哈希值作为证书的签名;并用私钥1对签名进行了加密处理.之后客户端用公钥1对签名进行解密,并计算证书的MD5值,与签名中的MD5值进行对比,如果相同就说明证书的内容没有被修改过.然后客户端生成对称密钥,取出证书中的公钥2,对对称密钥进行加密并发送给服务端,服务端使用私钥2对对称密钥进行解密,此时服务器端和客户端就都获取到了一样的对称密钥,之后双方传输的数据就采用对称密钥进行加密.
- 第二组非对称加密的密钥是为了让客户端把这个对称密钥传给服务器.
- 第一组非对称加密的密钥是为了让客户端拿到第二组非对称加密的公钥
第一组非对称加密的私钥和公钥是从CA机构间获取的,
第二组非对称加密的私钥和公钥是服务器端生成的
对称加密的密钥是客户端生成的
这个过程中涉及到了对称加密,非对称加密,哈希函数,哈希函数主要是通过证书的内容生成签名,用来验证证书是否被修改过.
通信过程的总结:
1.TCP三次握手建立连接
2.TLS握手协商密钥
3.正常通信