如果你打开一个网站,看看地址栏,就会发现大多数网站地址上有个https:www.xxx.com。https和http相比就多了个s。他们之间是有关系的。先讨论HTTP。HTTP全称“超文本传输协议”,是非常常用的应用层协议。平时打开的网站使用了HTTP协议来传输的。
HTTP协议格式
上图为抓包的截图,发送了一个HTTP请求,从浏览器输入一些东西后,产生的。该截图第一行显示 POST + 网站网址 + HTTP/1.1。从第二行开始到空行之间,是一些键值对,以:作为分隔符。每一行的结尾只是换行。空行以下就是一些看不懂的东西了。
格式如下:
- 首行:【方法】+【URL】+【HTTP协议版本】
- Header:请求的属性。冒号分割键值对,每一组属性之间使用换行分割。一直到空行表示Header表示结束。
- Body:空行部分之后是Body,允许为字符串。如果Body存在,在Header部分会有一个Content-Length标识长度。
上图是抓包的部分截图,是HTTP响应,浏览器获取到数据后,从服务器返回的数据(和发送HTTP请求截图无关)。发现报文格式和HTTP请求的很相似,首行是版本号 + 200 + ok,接下来就是Header部分,表示请求的属性,仍然是以冒号来分割键值对,一直遇到空行。空行结束后,就是Body。如果Body存在,在Header中会有一个Content-Length属性标识长度。Body部分是一个html页面。
格式如下:
- 首行:【版本号】+【状态码】+【状态码解释说明】
- Header:请求的属性。冒号分割键值对,每一组属性之间使用换行分割。一直到空行表示Header表示结束。
- Body:空行部分之后是Body,允许为字符串。如果Body存在,在Header部分会有一个Content-Length标识长度。
总结:
HTTP请求
URL
URL是“网站地址”。互联网上的每一个文件有唯一的URL,包含的信息指出文件位置以及浏览器如何处理。
实际中的URL如下图:
- https:协议方案名。可以省略。
- user:pass:登录信息,现在不在通过类似方式,可以省略。
- cn.bing.com:服务器地址。会通过DNS系统解析成一个具体的IP地址。
- 端口号:服务器中特定进程提供的服务。省略的时候,浏览器根据协议自动使用哪一个端口号。http协议默认使用80端口,https协议默认使用433端口号。可以省略。
- search:带层次的文件路径,表示访问哪个文件。一个应用下,可能管理很多的资源,描述了要访问的服务器的什么资源。可以省略
- q=百度&...:查询字符串 query string,本质是一个键值对结构,键值对之间使用&分割。可以省略
- 片段标识符:主要用于页面的跳转。可以省略
当URL中出现/?等这样的字符,就需要进行转义(URL encode)。这里不再讨论。
方法
GET方法
GET方法是最常用的HTTP方法,常用于获取服务器上的某个资源。在浏览器中输入URL,浏览器就会发送一个GET请求。特点如下:
- 首行第一部分为GET。
- URL的query string 可以为空,也可以不为空。
- head 部分有若干个键值对结构。
- body 部分为空。
- GET的数据的传递一般通过query string传递。
对一个GET请求进行抓包,就能看见GET的这些特性。
POST方法
POST方法多用于提交用户输入的数据给服务器(比如搜索)。特点如下:
- 首行第一部分为POST。
- URL的query string一般为空。
- header部分有若干个键值对结构。
- body部分一般不为空。body 内的数据格式通过 header 中的 Content-Type 指定。body 的长度由 header 中的 Content-Length 指定。
- POST的query string一般为空,数据传递一般是通过body。
其他的方法如PUT、DELETE方法等就不再介绍。这些方法的HTTP请求可以通过ajax来进行构造。
Header
Header的整体格式是键值对的结构,每一个键值对占用一行,键和值之间使用分号进行分割。
- Host:表示服务器主机的地址和端口。
- Content-Length:表示body中的数据长度。
- Content-Type:表示请求的body中的数据格式。
UA
表示浏览器/操作系统的属性。这个属性的存在因为历史的原因,这里不做介绍。
Referer
表示从什么页面中跳转过来。直接在浏览器中输入URL或直接在收藏夹中访问页面是没有Referer的。
Cookie
存储了字符串,包括一些用户的身份信息。Cookie的数据可能是网页自动通过js写入,也可能是HTTP响应的header通过Set-Cookie字段给浏览器返回数据。
如果我们第一次登录某个网站,该网站就会提示输入信息。当我们下一次登录的时候,发现就不需要输入信息了。这个过程中,浏览器就会保存这些Cookie。当我们删除后再次登录,就会提示需要输入信息。
Body
和Header中的Content-Type有关。
- application/x-www-form-urlencoded: form 表单提交的数据格式。
- multipart/form-data: form 表单提交的数据格式(在 form 标签中加上 enctyped="multipart/form-data" ),通常用于提交图片/文件。
- application/json: 数据为 json 格式。
HTTP响应
状态码
状态码表示访问一个页面的结果。
- 200 OK:表示访问成功。
- 404 Not Found:表示没有找到资源。
- 403 Forbidden:表示访问被拒绝,需要一定的权限。
- 500 Internal Server Error:表示服务器的问题。
- 302 Move temporarily:重定向,用来跳转页面。
Header
基本格式和请求报文的格式基本一致,不在累述。
Body
响应报文的格式取决于响应报文的Content-Type。常见的有html、css、js等。和请求报文的body格式相同。
HTTPS
HTTPS在HTTP的基础上进行了加密,进一步保证用户的信息安全。
对称加密
通过同一个“密钥”,把明文加密成密文,也能把密文加密成明文。比较典型的就是凯撒密码。约定好后移几位后,将字母使用后移了几位的字母代替来达到加密的过程。
非对称加密
非对称加密要用到两个密钥, 一个叫做 "公钥",一个叫做 "私钥"。
公钥和私钥是配对的。最大的缺点就是运算速度非常慢,比对称加密要慢很多:
- 通过公钥对明文加密,变成密文。
- 通过私钥对密文解密,变成明文。
也可以反着用:
- 通过私钥对明文加密,变成密文。
- 通过公钥对密文解密,变成明文。
证书
证书进一步在客户端和服务器刚一建立连接的时候,服务器给客户端返回一个证书。这个证书包含了刚才的公钥,也包含了网站的身份信息。
当客户端获取到这个证书之后,会对证书进行校验(防止证书是伪造的)。判定证书的有效期是否过期、判定证书的发布机构是否受信任(操作系统中已内置的受信任的证书发布机构)。
验证证书是否被篡改: 从系统中拿到该证书发布机构的公钥,对签名解密,得到一个 hash 值(称为数据摘要), 设为 hash1。然后计算整个证书的 hash 值,设为 hash2。对比 hash1 和 hash2 是否相等。如果相等,则说明证书是没有被篡改过的。
非对称加密和证书的引入都是为了辅助对称加密来进一步保证用户的安全。