Http协议基于文本传输协议,位于 OSI 网络模型中的应用层。协议由之前的 RFC2616 拆分成立六个单独的协议说明 RFC7230 RFC7231 RFC7232 RFC7233 RFC7234 RFC7235 http 协议中报文以明文方式进行传输,不做任何加密。
1. Header
包括通用头,请求头,响应头,实体头四部分组成,每个头域由域名,冒号,域值组成。域名是大小写无关,域值前加任何数量的空格符,头域可以被扩展成多行,每行开始处,至少有一个空格符或制表符。
1.1. 通用头
通用头域包括请求和响应消息都支持的头域,提供了报文最基本的信息,包括:
Connection允许客户端和服务器指定与请求/响应连接有关的选项。Date报文创建时间。MINE-Version给出发送端使用的MINE版本。Trailer如果报文采用了分块传输编码(chunked transfer encoding)方式,就可以用这个首部列出报文挂托(Trailer)部分的首部集合。Transfer-Enciding告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式。Upgrade给出发送端想要“升级”使用的新版本和协议。Via显示报文经过的中间节点
对通用头域的扩展要求通信双方都支持扩展,如果存在不支持的头域,一般将作为实体头域去处理。
1.2. 请求头
请求消息的第一行为下面的格式:
MethodSPRequest-URISPHTTP-VersionCRLFMethod
SP表示空格。Request-URI遵循URI格式,在此字段为星 号(*)时,说明请求并不用于某个特定的资源地址,而是用于服务器本身。HTTP-Version表示支持的HTTP版本,例如为HTTP/1.1。CRLF表示换行回车符。
请求头域允许客户端向服务器传递关于请求或者关于客户端信息。请求头域可包含字段 Accept Accept-Charset Accept- Encoding Accept-Language Authorization From Host If-Modified-Since If- Match If-None-Match If-Range If-Range If-Unmodified-Since Max-Forwards Proxy-Authorization Range Referer User-Agent 。对请求头域的扩展要求通讯双方都支持,如果存在不支持的请求头域,一般将会作为 实体 处理。
对于 Request-URI 完成的方法,这个字段是大小写敏感的,包括 OPTIONS GET HEAD POST PUT DELETE TRACE 。方法 GET 和 HEAD 应该被所有的通用WEB服务器支持,其他所有方法的实现是可选的。GET 方法取回由 Request-URI 标识的信息。 HEAD 方法也是取回由 Request-URI 标识的信息,只是可以在响应时,不返回消息体。POST 方法可以请求服务器接收包含在请求中的实体信息,可以用于提交表单,向新闻组、BBS、邮件群组和数据库发送消息。
GET http://download.google.com/somedata.exe
Host: download.google.com
Accept:*/*
Pragma: no-cache
Cache-Control: no-cache
Referer: http://download.google.com/
User-Agent:Mozilla/4.04[en](Win95;I;Nav)
Range:bytes=554554-
1.2.1. Host
指定请求资源的主机和端口号,必须表示请求 url 的原始服务器或网关的位置。 HTTP/1.1 请求必须包含主机头域,否则系统会以 400 状态码返回。
1.2.2. Pragma
Pragma头域用来包含实现特定的指令,最常用的是Pragma:no-cache。在HTTP/1.1协议中,它的含义和Cache- Control:no-cache相同。
1.2.3. Cache-Control
指定请求和响应遵循的缓存机制。在请求消息或响应消息中设置 Cache-Control并不会修改另一个消息处理过程中的缓存处理过程。请求时的缓存指令包括 no-cache no-store max-age max-stale min-fresh only-if-cached ,响应消息中的指令包括 public private no-cache no- store no-transform must-revalidate proxy-revalidate max-age 。消息中指令含义:
Public指示响应可被任何缓存区缓存。Private指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效。no-cache指示请求或响应消息不能缓存。no-store用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。max-age指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。min-fresh指示客户机可以接收响应时间小于当前时间加上指定时间的响应。 max-stale指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。
1.2.4. Referer
允许客户端指定请求uri的源资源地址,这可以允许服务器生成回退链表,可用来登陆、优化 cache 等。他也允许废除的或错误的连接由于维护的目的被追踪。如果请求的 uri 没有自己的 uri 地址,Referer 不能被发送。如果指定的是部分 uri 地址,则此地址应该是一个相对地址。
1.2.5. User-Agent
User-Agent头域的内容包含发出请求的用户信息。
1.2.6. Range
可以请求实体的一个或者多个范围。例如:
bytes=0-499表示头500个字节。bytes=500-999表示第二个500字节。bytes=-500表示最后500个字节。bytes=500-表示500字节以后的范围。bytes=0-0,-1第一个和最后一个字节。bytes=500-600,601-999同时指定几个范围。
服务器可忽略此请求头,如果无条件 GET 包含 Range 请求头,响应会以状态码206
PartialContent返回而不是以200OK。
1.3. 响应头
响应消息的第一行格式:
HTTP-VersionSPStatus-CodeSPReason-PhraseCRLF
HTTP -VersionHTTP 版本,例如为HTTP/1.1。Status- Code状态码详见2是一个三个数字的结果代码,主要用于机器自动识别。Reason-Phrase为 Status-Code 提供一个简单的文本描述,帮助用户理解。
响应头允许服务器传递不能放在状态行的附加信息,这些域主要描述服务器的信息和 Request-URI 进一步的信息。包含 Age Location Proxy-Authenticate Public Retry- After Server Vary Warning WWW-Authenticate 。对响应头域的扩展要求通讯双方都支持,如果存在不支持的响应头,会作为实体头域处理。
HTTP/1.0200OK
Date:Mon,31Dec200104:25:57GMT
Server:Apache/1.3.14(Unix)
Content-type:text/html
Last-modified:Tue,17Apr200106:46:28GMT
Etag:"a030f020ac7c01:1e9f"
Content-length:39725426
Content-range:bytes554554-40279979/40279980
1.3.1. Date
Date头域表示消息发送的时间,时间的描述格式由rfc822定义。例如,Date:Mon,31Dec200104:25:57GMT。Date描述的时间表示世界标准时,换算成本地时间,需要知道用户所在的时区。
1.3.2. Server
处理请求的原始服务器的软件信息。此域能包含多个产品标识和注释,产品标识一般按照重要性排序。
1.3.3. Content-Type
向接收方指示实体的介质类型,指定 HEAD 方法送到接收方的MIME 类型,或 GET 方法发送的请求介质类型 Content-Range 实体。后面的文档属于什么。Servlet默认为 text/plain ,但通常需要显式地指定为 text/html 。由于经常要设置 Content-Type,因此 HttpServletResponse 提供了一个专用的方法 setContentTyep 。
1.3.4. Last-modified
文档的最后改动时间。客户可以通过If-Modified-Since请求头提供一个日期,该请求将被视为一个条件GET,只有改动时间迟于指定时间的文档才会返回,否则返回一个304 Not Modified 状态。Last-Modified 也可用 setDateHeader 方法来设置。
1.3.5. Content-Range
实体头用于指定整个实体中的一部分的插入位置,他也指示了整个实体的长度。在服务器向客户返回一个部分响应,它必须描述响应覆盖的范围和整个实体长度。一般格式:
Content-Range:bytes-unitSPfirst-byte-pos-last-byte-pos/entity-legth
例如:传送头500个字节次字段的形式:Content-Range:bytes0- 499/1234如果一个http消息包含此节(例如,对范围请求的响应或对一系列范围的重叠请求),Content-Range表示传送的范围, Content-Length表示实际传送的字节数。
1.3.6. Location
表示客户应当到哪里去提取文档,通常不是直接设置的,通过 HttpServletResponse.sendRedirect() 方法,该方法同时设置状态代码为 302 。
1.4. 实体
请求消息和响应消息都可以包含实体信息,实体信息一般由实体头域和实体组成。实体头域包含关于实体的原信息,包括 Allow Content- Base Content-Encoding Content-Language Content-Length Content-Location Content-MD5 Content-Range Content-Type Etag Expires Last-Modified extension-header 。extension-header 允许客户端定义新的实体头,但是这些域可能无法未接受方识别。实体可以是一个经过编码的字节流,它的编码方式由 Content-Encoding 或 Content-Type 定义,它的长度由 Content-Length 或 Content-Range 定义。
| 应答 | 说明 |
|---|---|
| Allow | 服务器支持哪些请求方法(如GET、POST等) |
| Content-Encoding | 文档的编码(Encode)方法。只有在解码之后才可以得到Content-Type头指定的内容类型。利用gzip压缩文档能够显著地减少HTML文档的下载时间。Java GZIPOutputStream 可以很方便地进行 gzip 压缩,但只有Unix上 Netscape 和Windows上的IE 4、IE 5才支持它。因此,Servlet 应该通过查看 Accept-Encoding 头(即request.getHeader("Accept- Encoding"))检查浏览器是否支持 gzip ,为支持 gzip 的浏览器返回经 gzip 压缩的HTML页面,为其他浏览器返回普通页面 |
| Content-Length | 内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据。可以把输出报文写入 ByteArrayOutputStram ,其大小等价于 Content-Length ,最后通过 byteArrayStream.writeTo(response.getOutputStream()) 发送内容。 |
| Expires | 应该在什么时候认为文档已经过期,从而不再缓存它。 |
| Refresh | 表示浏览器应该在多少时间之后刷新文档,以秒计。除了刷新当前文档之外,你还可以通过 setHeader("Refresh", "5; URL=http://host/path") 让浏览器读取指定的页面。 注:通过设置HTML页面HEAD区的 META HTTP-EQUIV="Refresh" CONTENT="5;URL=http://host/path"实现,自动刷新或重定向对于不能使用CGI或Servlet的 HTML 编写者十分重要。对于Servlet来说,直接设置Refresh头更加方便 Refresh表示N秒之后刷新本页面或访问指定页面,而不是每隔N秒刷新本页面或访问指定页面。因此,连续刷新要求每次都发送一个Refresh头,而发送 204 状态代码则可以阻止浏览器继续刷新 Refresh头不属于HTTP 1.1正式规范的一部分,而是一个扩展,但Netscape和IE都支持它 |
| Set-Cookie | 设置和页面关联的Cookie。使用 HttpServletResponse.addCookie() |
| WWW-Authenticate | 客户端在Authorization头中提供授权信息,在包含401 Unauthorized 状态行的应答中这个头是必需的。例如, response.setHeader("WWW-Authenticate", "BASIC realm=\"executives\"")注: Servlet 一般不进行这方面的处理,而是让Web服务器的专门机制来控制受密码保护页面的访问(例如.htaccess) |
2. 状态码
100 - 199 指定客户端相应的某些动作, 200 - 299 表示请求成功, 300 - 399 已经移动的文件并且常被包含在定位头信息中指定新的地址信息, 400 - 499 指出客户端的处错误,500 - 599 支持服务器错误。
2.1. 100 - 199
100继续
服务器收到头信息中带有 100-continue 的请求,这是指客户端询问是否可以在后续的请求中发送附件。在这种情况下,服务器用100 SC_CONTINUE 允许客户端继续或用417 Expectation Failed 告诉客户端不同意接受附件。这个状态码是 HTTP 1.1 中新加入的。
101转换协议
SC_SWITCHING_PROTOCOLS 状态码是指服务器将按照其上的头信息变为一个不同的协议。这是 HTTP 1.1 中新加入的。
2.2. 200 - 299
200正常
SC_OK 的意思是一切正常。一般用于相应 GET 和 POST 请求。这个状态码对 servlet 是缺省的,如果没有调用 setStatus 方法的话,就会得到200。
201已创建
SC_CREATED 表示服务器在请求的响应中建立了新文档,应在定位头信息中给出它的URL。
202接受
SC_ACCEPTED 告诉客户端请求正在被执行,但还没有处理完。
203非官方信息
SC_NON_AUTHORITATIVE_INFORMATION 是表示文档被正常的返回,但是由于正在使用的是文档副本所以某些响应头信息可能不正确。这是 HTTP 1.1 中新加入的。
204无内容
在并没有新文档的情况下, SC_NO_CONTENT 确保浏览器继续显示先前的文档。这各状态码对于用户周期性的重载某一页非常有用,并且你可以确定先前的页面是否已经更新。
205重置内容
重置内容 SC_RESET_CONTENT 的意思是虽然没有新文档但浏览器要重置文档显示。这个状态码用于强迫浏览器清除表单域。这是 HTTP 1.1 中新加入的。
206局部内容
SC_PARTIAL_CONTENT 是在服务器完成了一个包含Range头信息的局部请求时被发送的。这是 HTTP 1.1 中新加入的。
2.3. 300 - 399
300多重选择
SC_MULTIPLE_CHOICES 表示被请求的文档可以在多个地方找到,并将在返回的文档中列出来。如果服务器有首选设置,首选项将会被列于定位响应头信息中。
301Moved Permanently
SC_MOVED_PERMANENTLY 状态是指所请求的文档在别的地方,文档新的 URL 会在定位响应头信息中给出。浏览器会自动连接到新的 URL 。
302Found / 找到
与301有些类似,只是定位头信息中所给的URL应被理解为临时交换地址而不是永久的。注意:在 HTTP 1.0 中,消息是临时移动 Moved Temporarily 的而不是被找到,因此 HttpServletResponse 中的常量是 SC_MOVED_TEMPORARILY 不是我们以为的 SC_FOUND 。
代表状态码302的常量是 SC_MOVED_TEMPORARILY 而不是 SC_FOUND 。
状态码302是非常有用的因为浏览器自动连接在定为响应头信息中给出的新URL。这非常有用,而且为此有一个专门的方法 sendRedirect 。使用 response.sendRedirect(url) 比调用 response.setStatus(response.SC_MOVED_TEMPORARILY) 和 response.setHeader("Location", url) 多几个好处。首先, response.sendRedirect(url) 方法明显要简单和容易。第二,servlet 自动建立一页保存这一连接以提供给那些不能自动转向的浏览器显示。最后,在 servlet 2.2 版本(J2EE中的版本)中,sendRedirect 能够处理相对路径,自动转换为绝对路径。但是你只能在2.1版本中使用绝对路径。
如果你将用户转向到站点的另一页中,你要用 HttpServletResponse 中的 encodeURL 方法传送 URL 。这么做可预防不断使用基于 URL 重写的会话跟踪的情况。URL 重写是一种在你的网站跟踪不使用 cookies 的用户的方法。这是通过在每一个 URL 尾部附加路径信息实现的,但是 servlet 会话跟踪 API 会自动的注意这些细节。
303See Other / 参见其他信息
这个状态码和 301、302 相似,只是如果最初的请求是 POST,那么新文档(在定位头信息中给出)要用 GET 找回。这个状态码是新加入 HTTP 1.1 中的。
304Not Modified / 未修正
当客户端有一个缓存的文档,通过提供一个 If-Modified-Since 头信息可指出客户端只希望文档在指定日期之后有所修改时才会重载此文档,用这种方式可以进行有条件的请求。304(SC_NOT_MODIFIED)是指缓冲的版本已经被更新并且客户端应刷新文档。另外,服务器将返回请求的文档及状态码 200。servlet一般情况下不会直接设置这个状态码。它们会实现 getLastModified 方法并根据修正日期让默认服务方法处理有条件的请求。这个方法的例程已在2.8部分( An Example Using Servlet Initialization and Page Modification Dates 一个使用 servlet 初始化和页面修正日期的例子)给出。
305Use Proxy / 使用代理
305(SC_USE_PROXY)表示所请求的文档要通过定位头信息中的代理服务器获得。这个状态码是新加入 HTTP 1.1 中的。
307临时重定向
浏览器处理307状态的规则与302相同。307状态被加入到 HTTP 1.1 中是由于许多浏览器在收到 302 响应时即使是原始消息为 POST 的情况下仍然执行了错误的转向。只有在收到 303 响应时才假定浏览器会在 POST 请求时重定向。添加这个新的状态码的目的很明确:在响应为 303 时按照 GET 和 POST 请求转向,而在 307 响应时则按照 GET 请求转向而不是 POST 请求。
注:由于某些原因在 HttpServletResponse 中还没有与这个状态对应的常量。该状态码是新加入
HTTP 1.1中的。
在 HttpServletResponse 中没有 SC_TEMPORARY_REDIRECT 常量,所以你只能显示的使用307状态码。
2.4. 400 - 499
400错误请求
SC_BAD_REQUEST 指出客户端请求中的语法错误。
401未授权
SC_UNAUTHORIZED 表示客户端在授权头信息中没有有效的身份信息时访问受到密码保护的页面。这个响应必须包含一个WWW-Authenticate的授权信息头。例如:Restricting Access to Web Pages. 限制访问Web页。”
403禁止
SC_FORBIDDEN 的意思是除非拥有授权否则服务器拒绝提供所请求的资源。这个状态经常会由于服务器上的损坏文件或目录许可而引起。
404未找到
SC_NOT_FOUND 状态每个网络程序员可能都遇到过,他告诉客户端所给的地址无法找到任何资源。它是表示“没有所访问页面”的标准方式。
405方法未允许
SC_METHOD_NOT_ALLOWED 指出请求方法 GET POST HEAD PUT DELETE 等对某些特定的资源不允许使用。该状态码是新加入 HTTP 1.1 中的。
406无法访问
SC_NOT_ACCEPTABLE 表示请求资源的MIME类型与客户端中 Accept 头信息中指定的类型不一致。406是新加入 HTTP 1.1 中的。
407代理服务器认证要求
SC_PROXY_AUTHENTICATION_REQUIRED 与 401 状态有些相似,只是这个状态用于代理服务器。该状态指出客户端必须通过代理服务器的认证。代理服务器返回一个 Proxy-Authenticate 响应头信息给客户端,这会引起客户端使用带有 Proxy-Authorization 请求的头信息重新连接。该状态码是新加入 HTTP 1.1 中的。
408请求超时
SC_REQUEST_TIMEOUT 是指服务端等待客户端发送请求的时间过长。该状态码是新加入 HTTP 1.1 中的。
409冲突
该状态通常与PUT请求一同使用,SC_CONFLICT 状态常被用于试图上传版本不正确的文件时。该状态码是新加入 HTTP 1.1 中的。
410 已经不存在
SC_GONE 告诉客户端所请求的文档已经不存在并且没有更新的地址。410 状态不同于 404 ,410 是在指导文档已被移走的情况下使用,而 404 则用于未知原因的无法访问。该状态码是新加入 HTTP 1.1 中的。
411需要数据长度
SC_LENGTH_REQUIRED 表示服务器不能处理请求(假设为带有附件的POST请求),除非客户端发送 Content-Length 头信息指出发送给服务器的数据的大小。该状态是新加入 HTTP 1.1 的。
412先决条件错误
SC_PRECONDITION_FAILED 状态指出请求头信息中的某些先决条件是错误的。该状态是新加入 HTTP 1.1 的。
413请求实体过大
SC_REQUEST_ENTITY_TOO_LARGE 告诉客户端现在所请求的文档比服务器现在想要处理的要大。如果服务器认为能够过一段时间处理,则会包含一个 Retry-After 的响应头信息。该状态是新加入 HTTP 1.1 的。
414请求URI过长
SC_REQUEST_URI_TOO_LONG 状态用于在 URI 过长的情况时。这里所指的“URI”是指 URL 中主机、域名及端口号之后的内容。例如: 在URL--http://www.y2k-disaster.com:8080/we/look/silly/now/ 中 URI 是指 /we/look/silly/now/ 。该状态是新加入 HTTP 1.1 的。
415不支持的媒体格式
SC_UNSUPPORTED_MEDIA_TYPE 意味着请求所带的附件的格式类型服务器不知道如何处理。该状态是新加入 HTTP 1.1 的。
416请求范围无法满足
SC_REQUESTED_RANGE_NOT_SATISFIABLE 表示客户端包含了一个服务器无法满足的Range头信息的请求。该状态是新加入 HTTP 1.1 的。奇怪的是,在 servlet 2.1 版本 API 的 HttpServletResponse 中并没有相应的常量代表该状态。在 servlet 2.1 的规范中,类 HttpServletResponse 并没有 SC_REQUESTED_RANGE_NOT_SATISFIABLE 这样的常量,所以你只能直接使用 416。在servlet 2.2版本之后都包含了此常量。
417期望失败
如果服务器得到一个带有100-continue值的 Expect 请求头信息,这是指客户端正在询问是否可以在后面的请求中发送附件。在这种情况下,服务器也会用该状态 417 Expectation Failed 告诉浏览器服务器不接收该附件或用100(SC_CONTINUE)状态告诉客户端可以继续发送附件。该状态是新加入 HTTP 1.1 的。
2.5. 500 - 599
500内部服务器错误
SC_INTERNAL_SERVER_ERROR ****是常用的“服务器错误”状态。该状态经常由CGI程序引起也可能(但愿不会如此!)由无法正常运行的或返回头信息格式不正确的 servlet 引起。
501未实现
SC_NOT_IMPLEMENTED 状态告诉客户端服务器不支持请求中要求的功能。例如,客户端执行了如PUT这样的服务器并不支持的命令。
502错误的网关
SC_BAD_GATEWAY 被用于充当代理或网关的服务器;该状态指出接收服务器接收到远端服务器的错误响应。
503服务无法获得
状态码 SC_SERVICE_UNAVAILABLE 表示服务器由于在维护或已经超载而无法响应。例如,如果某些线程或数据库连接池已经没有空闲则 servlet 会返回这个头信息。服务器可提供一个 Retry-After 头信息告诉客户端什么时候可以在试一次。
504网关超时
Gateway Timeout 该状态也用于充当代理或网关的服务器;它指出接收服务器没有从远端服务器得到及时的响应。该状态是新加入 HTTP 1.1 的。
505不支持的 HTTP 版本
SC_HTTP_VERSION_NOT_SUPPORTED 状态码是说服务器并不支持在请求中所标明 HTTP 版本。该状态是新加入 HTTP 1.1 的。
3. 网络劫持
用户的客户端与其访问的服务器经过网络协议协调后,二者之间建立了一条专用的数据通道,用户端程序在系统中开放指定网络端口用于接收数据报文,服务端将全部数据按指定网络协议规则进行分解打包,形成连续数据报文。
3.1. 原理
用户的浏览器上被访问的网站服务器,发送了HTTP请求后,运营商的路由器会首先收到此次HTTP请求,之后运营商路由器的旁路设备标记此次TCP连接为HTTP协议,之后可以在网站服务器返回数据之前发送HTTP协议的302代码进行下载软件的劫持,浏览器收到302代码后就会跳转到错误的软件下载地址下载软件,随后网站服务器的真正数据到达后反而会被丢弃。或者旁路设备在标记此TCP连接为HTTP协议后,直接返回修改后的HTML代码,导致浏览器中被插入运营商广告,随后网站服务器的真正数据到达最终也是被丢弃。
从上述原理中看出,如果需要进行HTTP劫持,首先需要进行标记:如果是HTTP协议,那么进行劫持,否则不进行劫持。那么,是否有一种方法,既可以避免被旁路设备标记为HTTP协议,而目标网站收到的仍旧是原来的HTTP请求,
3.2. 处理
如果确认遭遇了HTTP劫持,可以向ISP(互联网服务提供商,即向广大用户综合提供互联网接入业务、信息业务、和增值业务的电信运营商。)客服强烈投诉,来达到免于被劫持的目的。因为劫持技术本身设计中包括类似黑名单的功能,如果收到宽带用户的强烈反对,ISP会将该用户放入"黑名单"过滤掉,于是用户在短期内就不会遇到劫持的情况了。
HTTPS的出现对利用网络劫持的企业来说,无疑是一个巨大的打击。 HTTPS 的出现,通过对数据的加密,使得第三方难以修改我们的数据内容。就像字条上的文字只有甲方跟丙方能够看懂,作为乙方根本不知道纸条上写的是什么内容,就不从下手对内容进行修改。同时,给字条加上信封,再加上一次性的印戳,使得乙方根本无法看到字条上的内容,因为一旦拆开信封,丙方就知道自己的信息被第三方看到了,从而对纸条内容产生怀疑。SSL证书就像信封,把我们的数据放在里面,只有指定的一方可以解读这个数据,一旦数据被第三方劫持,接受数据的用户就会产生不信任,从而丢弃数据。
4. HTTPS
通过 RSA 算法来实现。在约定加密方式的时候由服务器生成一对公私钥,服务器将公钥返回给客户端,客户端本地生成一串秘钥( AES_KEY )用于对称加密,并通过服务器发送的公钥进行加密得到(AES_KEY_SECRET),之后返回给服务端,服务端通过私钥将客户端发送的 AES_KEY_SECRET 进行解密得到 AEK_KEY ,最后客户端和服务器通过 AEK_KEY 进行报文的加密通讯。
SSL + HTTP的简称,SSL 基本已经被 TLS 取代了,不过接下来我们还是统一以 SSL 作为简称,SSL 协议其实不止是应用在 HTTP 协议上,还在应用在各种应用层协议上,例如: FTP WebSocket。SSL 协议大致就和上方非对称加密的性质一样,握手的过程中主要也是为了交换秘钥,然后再通讯过程中使用对称加密进行通讯,大概流程如下:
4.1. CA认证体系
服务器是通过 SSL 证书来传递公钥,客户端会对 SSL 证书进行验证,其中证书认证体系就是确保SSL安全的关键。
权威认证机构
在 CA 认证体系中,所有的证书都是由权威机构来颁发,而权威机构的 CA 证书都是已经在操作系统中内置的,我们把这些证书称之为CA根证书:
签发证书
应用服务器如果想要使用 SSL 的话,需要通过权威认证机构来签发CA证书,将服务器生成的公钥和站点相关信息发送给CA签发机构,再由CA签发机构通过服务器发送的相关信息用CA签发机构进行加签,由此得到我们应用服务器的证书,证书会对应的生成证书内容的签名,并将该签名使用CA签发机构的私钥进行加密得到证书指纹,并且与上级证书生成关系链。
百度证书
可以看到百度是受信于GlobalSign G2,同样的GlobalSign G2是受信于GlobalSign R1,当客户端(浏览器)做证书校验时,会一级一级的向上做检查,直到最后的根证书,如果没有问题说明服务器证书是可以被信任的。如何验证服务器证书那么客户端(浏览器)又是如何对服务器证书做校验的呢,首先会通过层级关系找到上级证书,通过上级证书里的公钥来对服务器的证书指纹进行解密得到签名(sign1),再通过签名算法算出服务器证书的签名(sign2),通过对比sign1和sign2,如果相等就说明证书是没有被篡改也不是伪造的。
证书校验用的 RSA 是通过私钥加密证书签名,公钥解密来巧妙的验证证书有效性。通过证书的认证体系,我们就可以避免了中间人窃取 AES_KEY 从而发起拦截和修改 HTTP 通讯的报文。