第六章 HTTP首部
6.1 HTTP报文首部
- HTTP协议的请求和响应报文中必定包含HTTP首部。首部内容为客户端和服务器分别处理请求和响应提供所需要的信息。
- 报文首部由几个字段构成
HTTP请求报文
-
在请求中,HTTP报文由方法、URI、HTTP版本、HTTP首部字段等部分构成。
-
例如:访问:http://hackr.jp时,请求报文的首部信息。
HTTP响应报文
-
在响应中,HTTP报文由HTTP版本、状态码(数字和原因短语)、HTTP首部字段3部分构成
- 例子:请求访问http://hackr.js时,返回的响应报文的首部信息
- 在报文众多的字段当中,HTTP首部字段包含的信息最为丰富。首部字段同事存在于请求和响应报文内,并涵盖HTTP报文相关的内容信息。
- 因HTTP版本或扩展规范的变化,首部字段可支持的字段内容略有不同。
6.2 HTTP首部字段
HTTP首部字段传递重要信息
- HTTP首部字段是构成HTTP报文的要素之一。在客户端与服务器之间以HTTP协议进行通信的过程中,无论是请求还是响应都会使用首部字段,它能起到传递额外重要信息的作用。
-
使用首部字段是我了给浏览器和服务器提供报文主体大小、所使用的语言、认证信息等内容
HTTP首部字段结构
-
HTTP首部字段是由首部字段名和字段值构成的,中间用冒号“:”分隔;
-
例如,在HTTP首部汇总以Content-Type这个字段来表示报文主体的对象类型。
- 就以上述示例来看,首部字段名为Content-Type,字符串text/html是字段值。
-
另外,字段值对应单个HTTP首部字段可以有多个值,如下所示:
若HTTP首部字段重复了会如何
- 当HTTP报文首部中出现了两个或两个以上具有哦相同首部字段名时会怎么样?这种情况在规范内尚未明确,根据浏览器内部处理逻辑的不同,结果可能并不一致。有些浏览器会有限处理第一次出现的首部字段,而有些则会优先处理最后出现的首部字段;
4种HTTP首部字段类型
- HTTP首部字段根据实际用途被分为一下4种类型。
通用首部字段
- 请求报文和响应报文两方都会使用的首部
请求首部字段
- 从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、响应内容相关优先级等信息。
响应首部字段
- 从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息。
实体首部字段
- 针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与试题有关的信息。
HTTP/1.1 首部字段一览
-
HTTP/1.1规范定义了如下47种首部字段。
非HTTP/1.1首部字段
- 在HTTP协议通信交互中使用到的首部字段,不限于RFC2616中定义的47种首部字段,还有Cookie、Set-Cookie和Content-Disposition等再其他RFC中定义的首部字段,他们的使用频率也很高。
- 这些非正式的首部字段统一归纳在RFC4229 HTTP Header Field Registrations中。
End - to - end首部和Hop - by - hop首部
- HTTP首部字段讲定义成缓存代理和非缓存代理的行为,分成2种类型。
端到端首部
- 分在此类别中的首部会转发给请求/响应对应的最终接收目标,且必须保存在由缓存生成的响应中,另外规定它必须被转发。
逐跳首部
- 粉在此类别中的首部只对单次转发有效,会因通过缓存或代理而不再转发。HTTP/1.1和之后版本中,如果要使用hop - by - hop首部,需提供Connection首部字段。
- 下面列举了HTTP/1.1中的逐跳首部字段,除这8个首部字段之外,其他所有字段都属于端到端首部
- Conncetion
- Keep-Alive
- Proxy-Authenticate
- Proxy-Authorization
- Trailer
- TE
- Transfer-Encoding
- Upgrade
6.3 HTTP/1.1通用首部字段
- 通用首部字段是指,请求报文和响应报文双方都会使用的首部。
Cache-Control
-
通过指定首部字段Cache-Control的指令,就能操作缓存的工作机制。
-
指令的参数是可选的,多个指令之间通过“,”分隔。首部字段Cache-Control的指令可用于请求及响应时。
Cache-Control指令一览
-
可用的指令按请求和响应分类如下所示:
- 表示是否能缓存的指令
public指令
- 当指定使用public指令时,则明确表明其他用户也可利用缓存。
private指令
- 当指定private指令后,响应只以特定的用户作为对象,这与public指令的行为相反。
- 缓存服务器会对该特定用户提供资源缓存的服务,对于其他用户发送过来的请求,代理服务器则不会返回缓存。
no-cache指令
- 使用no-cache指令的目的是为了防止从缓存中返回过期的资源。
- 客户端发送的请求中如果包含no-cache指令,则表示客户端讲不会接受缓存过的响应。于是,“中间”的缓存服务器必须把客户端请求转发给源服务器。
-
如果服务器返回的响应中包含no-cache指令,那么缓存服务器不能对资源进行缓存。源服务器以后也将不再对缓存服务器请求中提出的资源有效性进行确认,且禁止其对响应资源进行缓存操作。
- 由服务器返回的响应中,若报文首部字段Cache-Control中对no-cache字段名具体指定参数值,那么客户端在接收到这个被指定参数值的首部字段对应的响应报文后,就不能使用缓存。换言之,无参数值的首部字段可以使用缓存。只能在响应指令中指定该参数。
控制可执行缓存的对象的指令
no-store指令
- 当使用no-store指令时,暗示请求(和对应的响应)或响应汇总包含机密信息。
- 因此,该指令规定缓存不能在本地存储请求或响应的任一部分。
指定缓存期限和认证的指令
s-maxage指令
- s-maxage指令的功能和max-age指令的相同,它们的不同点是s-maxage指令只适用于供多位用户使用的公共缓存服务器。也就是说,对于向同一用户重复返回响应的服务器来说,这个指令没有任何作用。
- 另外,当使用s-macage指令后,则直接忽略对Expires首部字段及max-age指令的处理。
max-age指令
- 当客户端发送的请求中包含max-age指令时,如果判定缓存资源的缓存时间数值比指定时间的数值更小,那么客户端就接收缓存的资源。另外,当指定max-age值为0,那么缓存服务器通常需要将请求转发给源服务器。
- 当服务器返回的响应中包含max-age指令时,缓存服务器将不对资源的有效性再作确认,而max-age数值代表资源保存为缓存的最长时间。
- 应用HTTP/1.1版本的缓存服务器遇到同时存在Expires首部字段的情况时,会优先处理max-age指令,而忽略掉Expirse首部字段。而HTTP/1.0版本的缓存服务器的情况却相反,max-age指令会被忽略掉。
min-fresh指令
- min-fresh指令要求缓存服务器返回至少还未过指定时间的缓存资源。
- 比如,当指定min-fresh为60秒后,在这60秒以内如果有超过有效期限的资源都无法作为响应返回了。
max-stale指令
- 使用max-stale可指示缓存资源,即使过期也照常接收。
- 如果指令未指定参数值,那么无论经过多久,客户端都会接收响应;如果指令中指定了具体数值,那么即使过期,只要仍处于max-stale指定的时间内,仍旧会被客户端接收。
only-if-cached指令
- 使用only-if-cached指令表示客户端仅在缓存服务器本地缓存目标资源的情况下才会要求其返回。换言之,该指令要求缓存吴福气不重新加载响应,也不会再次确认资源有效性。若发生请求缓存服务器的本地缓存无响应,则返回状态码504 Gateway Timeout;
must-revalidate指令
- 使用must-revalidate指令,代理会向源服务器再次验证即将返回的响应缓存目前是否仍然有效。
- 若代理无法连通源服务器再次获取有效资源的话,缓存必须给客户端一条504状态码;
- 另外,使用must-revalidate指令会忽略请求的max-stale指令(即使已经在首部使用了max-stale,也不会再有效果)。
proxy-revalidate指令
- proxy-recalidate指令要求所有的缓存服务器在接收到苦短带有该指令的请求返回响应之前,必须再次验证缓存的有效性。
no-transform指令
- 使用no-transform指令规定无论是在请求还是响应中,缓存都不能改变试题主体的媒体类型。
- 这样做可防止缓存活代理压缩图片等类似操作。
Cache-Control拓展
cache-extension token
- 通过cache-extension标记(token),可以拓展Cache-Control首部字段内的指令。
- 如上例,Cache-Control首部字段本身没有community这个指令。借助extension tokens实现了该指令的添加。如果缓存服务器不能理解community这个新指令,就会直接忽略。因此,extension tokens仅对能理解它的缓存服务器来说是有意义的。
Connection
Connection首部字段具备如下两个作用
- 控制不再转发给代理的首部字段
- 管理持久连接
控制不再转发给代理的首部字段
- 在客户端发送请求和服务器返回响应内,使用Connection首部字段,可控制不再转发给代理的首部字段。
管理持久连接
-
HTTP/1.1版本的默认连接都是持久连接。为此,客户端会在持久连接上连续发送请求。当服务器端想明确断开连接时,则指定Connection首部字段的值为Close。
- HTTP/1.1之前的HTTP版本的默认连接都是非持久连接。为此,如果想在旧版本的HTTP协议上维持连接,则需要指定Conection首部字段的值为Keep-Alive。
- 为上图①所示,客户端发送请求给服务器时,服务器端会像上图②那样加上首部字段Keep-Alive及首部字段Connection后返回响应。
Date
-
首部字段Date表明创建HTTP报文的日期和时间。
-
HTTP/1.1协议使用在RFC1123中规定的日期时间的格式,如下实例:
-
之前的HTTP协议版本中使用在RFC850中定义的格式,如下实例:
-
除此之外,还有一种格式。它与C标准库内的asctime()函数的输出格式一致。
Pragma
- Pragma是HTTP/1.1之前版本的历史遗留字段,仅作为与HTTP/1.0的向后兼容而定义。
-
规范定义的形式唯一,如下所示:
-
该首部字段属于通用首部字段,但只用在客户端发送的请求中。客户端会要求所有的中间服务器不返回缓存的资源
-
所有的中间服务器如果都能以HTTP/1.1为基准,那直接采用Cache-Control:no-cache指定缓存的处理方式是最为理想的。但要整体掌握全部中间服务器使用的HTTP协议版本缺是不现实的。因此,发送的请求会同时含有下面两个首部字段。
Trailer
-
首部字段Trailer会事前说明在报文主体后记录了哪些首部字段。改首部字段可应用在HTTP/1.1版本分块传输编码时。
- 以上用例中,指定首部字段Trailer的值为Expires,在报文主体之后出现了首部字段Expires。
Transfer-Encoding
- 首部字段Transfer-Encoding规定了传输报文主体时采用的编码方式。
-
HTTP/1.1的传输编码方式仅对分块传输编码有效。
- 以上用例中,正如在首部字段Transfer-Encoding中指定的那样,有效使用分块传输编码,且分别被分成3312字节和914字节大小的分块数据。
Upgrade
-
首部字段Upgrade用于检测HTTP协议及其他协议是否可使用更高的版本进行通信,其参数值可以用来指定一个完全不同的通信协议。
- 上图用例汇总,首部字段Upgrade指定的值为TLS/1.0。请注意此处两个字段首部字段的对应关系,Connection的值被指定为Upgrade。Upgrade首部字段产生作用的Upgrade对象仅限于客户端和邻接服务器之间。因此,使用首部字段Upgrade时,还需要额外指定Connection:Upgrade。
- 对于附有首部字段Upgrade的请求,服务器可用101 Awitching Protocols状态码作为响应返回。
Via
- 使用首部字段Via是为了追踪客户端与服务器之间的请求和响应报文的传输路径。
- 报文经过代理或网关时,会先在首部字段Via中附加该服务器的信息,然后再进行转发。这个做法和traceroute及电子邮件的Received首部的工作机制很类似。
-
首部字段Via不仅用于追踪报文的转发,还可避免请求回环的发生。所以必须在经过代理时附加该首部字段内容。
- 上图用例中,在经过代理服务器A时,Via首部附加了“1.0 gw.hackr.jp”这样的字符串值。行头的1.0是指接收请求的服务器上应用的HTTP协议版本。接下来经过代理服务器B时亦是如此,在Via首部附加服务器信息,也可增加1个新的Via首部写入服务器信息。
- Via首部是为了追踪传输路径,所以经常会和TRACE方法一起使用。比如,代理服务器接收到由TRACE方法发送过来的请求时,代理服务器就不能再转发该请求了。这种情况下,代理服务器会将自身的信息附加到Via首部后,返回该请求的响应。
Warning
-
HTTP/1.1的Warning首部是从HTTP/1.0的首部演变过来的。该首部通常会告知用户一些与缓存相关的问题的警告。
-
Warning首部的格式如下。最后的日期时间部分可省略。
6.4 请求首部字段
-
请求首部字段是从客户端往服务器端发送请求报文中所使用的字段,用于补充请求的附加信息、客户端信息、对响应内容相关的优先级等内容。
Accept
- Accept首部字段可通知服务器,用户代理能够处理的媒体类型及媒体类型的相对优先级。可使用type/subtype这种形式,一次指定多种媒体类型。
- 下面我们试举几个媒体类型的例子。
- 文本文件
- text/html, text/plain, text/css....
- application/xhtml+xml, application/xml....
- 图片文件
- image/jpeg, image/gif, image/png....
- 视频文件
- video/mpeg, video/quicktime
- 应用程序使用的二进制文件
- application/octet-stream, application/zip...
- 文本文件
- 比如:如果浏览器不支持PNG图片的显示,那Accept就不指定image/png, 而指定可处理的image/gif和image/jpeg等图片类型。
- 若想要给显示的媒体类型增加优先级,则使用q=来额外表示权重值,用分号进行分隔。权重值q的范围是0~1,且1为最大值。不指定权重q值时,默认权重为q=1.0.
- 当服务器提供多种内容时,将会首先返回权重值值最高的媒体类型。
Accept-Charset
- Accept-Charset首部字段可用来通知服务器用户代理支持的字符集及字符集的相对优先顺序。另外,可一次性指定多种字符集。与首部字段Accept相同的是可用权重q值来表示相对优先级。
- 该首部字段应用于内容协商机制的服务器驱动协商。
Accept-Encoding
- Accept-Encoding首部字段用来告知服务器用户代理支持的内容编码及内容编码的优先级顺序。可一次性指定多种内容编码。
- 下面试举出几个内容编码的例子。
gzip
- 由文件压缩程序gzip生成的编码格式,采用Lempel-Ziv算法及32位循环冗余校验。
compress
- 由UNIX文件压缩程序compress生成的编码格式,采用Lempel-Ziv-Welch算法。
deflate
- 组合使用zlib格式及由deflate压缩算法生成的编码格式
identity
- 不执行压缩或不会辩护阿德默认编码格式
- 采用权重q值来表示相对优先级,这点与首部字段Accept相同。另外,也可使用星号作为通配符,指定任意的编码格式。
Accept-Language
- 首部字段Accept-Language用来告知服务器用户代理能够处理的自然语言集,以及自然语言集的相对优先级。可一次性指定多种自然语言集。
- 和Accept首部字段一样,按权重值q来表示相对优先级。在上述图例中,客户端在服务器有中文版资源的情况下,会请求其返回中文版对应的响应,没有中文版时,则请求返回英文版响应。
Authorization
- 首部字段Authorization是用来告知服务器,用户代理的认证信息。通常,想要通过服务器认证的用户代理会在接收到返回的401状态码响应后,吧首部字段Authorization加入请求中。公用缓存在接收到含有Authorization首部字段的请求时的操作处理会略有差异。
Expect
- 客户端使用首部字段Expect来告知服务器,期望出现的某种特定行为。因服务器无法理解客户端的期望作出回应而发生错误时,会返回状态码417 Expectation Failed。
- 客户端可以利用改首部字段,写明所期望的拓展。虽然HTTP/1.1规范只定义了100-continue。
- 等待状态码100响应的客户端在发生请求时,需要指定expect:100-continue。
From
- 首部字段From用来告知服务器使用用户代理的用户的电子邮件地址。通常,其使用目的就是为了显示搜索引擎等用户代理的负责人的电子邮件联系方式。使用代理时,应尽可能包含From首部字段。
Host
- 首部字段Host会告知服务器,请求的资源所处的互联网主机名和端口号。Host首部字段在HTTP/1.1规范内是唯一一个必须被包含在请求内的首部字段。
- 首部字段Host和以单台服务器分配多个域名的虚拟主机的工作机制有很密切的关联,这是首部字段Host必须存在的意义。
-
请求呗发送至服务器时,请求中的知己名会用IP地址直接替换解决。但如果这时,相同的IP地址下不熟运行着多个域名,那么服务器就会无法理解酒精是哪个域名对应的请求。因此,就需要使用首部字段Host来明确指出请求的主机名。若服务器未设定主机名,那直接发送一个空值即可。如下所示:
If-Match
-
形如If-xxx这种样式的请求首部字段,都可称为条件请求。服务器收到附带条件的请求后,只有判断指定条件为真时,才会执行请求。
- 首部字段If-Match,属附带条件之一,它会告知服务器匹配资源所用的试题标记值。这时的吴福气无法使用弱ETag值。
- 服务器会对比If-Match的字段值和资源的ETag值,仅当两者一致时,才会执行请求。反之,则返回状态码412 Precondition Failed的响应。
- 还可以使用型号指定If-Match的字段值。针对这种情况,服务器将会忽略ETag的值,只要资源存在就处理请求。
If-Modified-Since
- 首部字段If-Modified-Since,属附带条件之一,它会告知服务器若If-Modified-Since字段值早于资源的更新时间,则希望能处理该请求。而在指定If-Modified-Since字段值的日期时间之后,如果请求的资源都没有过更新,则返回状态码304 Not Modififed的响应。
- If-Modified-Since用于确认代理或客户端拥有的本地资源的有效性。获取资源的更新日期时间,可通过确认首部字段Last-Modified来确定。
If-None-Match
- 首部字段If-None-Match属于附带条件之一。它和首部字段If-Match作用相反。用于指定If-None-Match字段值的实体标记值与请求自愿的ETag不一致时,它就告知服务器处理该请求。
- 在GET或HEAD方法中使用首部字段If-None-Match可获取最新的资源。因此,这与使用首部字段If-Modified-Since时有些类似。
If-Range
-
首部字段If-Range属于附带条件之一。它告知服务器若指定的If-Range字段值和请求资源的ETag值或时间相一致时,则作为范围请求处理。反之,则返回全体资源。
- 如果不使用首部字段If-Range发送请求的情况。故武器端的资源如果更新,那客户端持有资源中的一部分也会随之无效,当然,范围请求作为前提是无效的。这时,服务器会暂且以状态码412 Precondition Failed作为响应返回,其目的是催促客户端再次发送请求。这样一来,与使用首部字段If-Range比起来,就需要花费两倍的功夫。
If-Unmodified-Since
- 首部字段If-Unmodified-Since和首部字段If-Modified-Since的作用相反。它的作用的是告知服务器,指定的请求资源只有在字段值内指定的日期时间之后,未发生更新的情况下,才能处理请求。如果在指定日期时间后发生了更新,则以状态码412 Precondition Failed作为响应返回。
Max-Forwards
- 通过TRACE方法或OPTIONS方法,发送包含首部字段Max-Forwards的请求时,该字段以十进制整数形式指定可经过的服务器做大数目。服务器在往下一个服务器转发请求之前,会将Max-Forwards的值减1后重新赋值。当服务器接收到Max-Forwards值为0的请求时,则不再进行转发,而是直接返回响应。
- 使用HTTP协议通信时,请求可能会经过代理等多台服务器。途中,如果代理服务器由于某些原因导致请求转发失败,客户端也就等不到服务器返回的响应了。
-
可以灵活使用首部字段Max-Forwards,针对以上问题产生的原因展开调查。由于当Max-Forwards字段值为0时,服务器就会理解返回响应,因此我们至少可以对以那台服务器未终点的传输路径的捅进状况有锁把握。
Proxy-Authorization
- 接收到从代理服务器发来的认证质询时,客户端会发送包含首部字段Proxy-Authorization的请求,以告知服务器认证所需要的信息。
- 这个行为是与客户端和服务器之间的HTTP访问认证相类似的,不同之处在于,认证行为未发生在客户端与代理之间。客户端与服务器之间的认证,使用首部字段Authorization可起到相同作用。
Range
- 对于只需获取部分资源的范围请求,包含首部字段Range即可告知服务器资源的指定范围。上面的示例表示请求获取从第5001字节至第10000字节的资源。
- 接收到附带Range首部字段请求的服务器,会在处理请求之后返回状态码206 Partial Content的响应。无法处理该范围请求时,则会返回状态码200 OK的响应及全部资源。
Referer
- 首部字段Refierer会告知服务器请求的原始资源的URI。
- 客户端一般都会发送Referer首部字段给服务器。但当直接在浏览器的地址栏输入URI,或出于安全性的考虑时,也可以不发送该首部字段。
- 因为原始资源的URI中的查询字符串可能含有ID和密码等保密信息,要是写进Referer转发给其他服务器,则有可能导致保密信息的泄漏。
- 另外,Referer的正确的拼写应该是Referrer,但不知为何,大家一致沿用这个错误的拼写。
TE
- 首部字段TE会告知服务器客户端能够处理响应的传输编码方式及相对优先级。它和首部字段Accept-Encoding的功能很相像,但是用于传输编码。
-
首部字段TE除指定传输编码之外,还可以指定伴随trailer字段的分块传输编码的方式,应用后者时,值需吧trailers赋值给该字段值。
User-Agent
- 首部字段User-Agent会将创建请求的浏览器和用户代理名称等信息传达给服务器。
- 由网络爬虫发起请求时,有可能会在字段内添加爬虫作者的电子邮件地址。此外,如果请求经过代理,那么中间也可能被添加上代理服务器的名称。
6.5 响应首部字段
-
响应首部字段是由服务器端向客户端返回响应报文中所使用的字段,用于补充响应的附加信息、服务器信息,以及对客户端的附加要求等信息。
Accept-Ranges
- 首部字段Accept-Ranges是用来告知客户端服务器是否能处理范围请求,以指定获取服务器端某个部分的资源。
- 可指定的字段值有两种,可处理范围请求时指定其为bytes,反之则指定其为none。
Age
- 首部字段Age能告知客户端,源服务器在多久前创建了响应。字段值的单位为秒。
- 若创建该响应的服务器是缓存服务器,Age值是值缓存后的响应再次发起认证到认证完成的的时间值。代理创建响应时必须加上首部字段Age。
ETag
- 首部字段ETag能告知客户端实体标识。它是一种可将资源以字符串形式做唯一性标识的方式。服务器会为每份资源分配对应的ETag。
-
另外,当资源更新时,ETag值也需要更新。生成ETag值时,并没有统一的算法规则,而仅仅是由服务器来分配。
- 资源被缓存时,就会被分配唯一性标识。例如,当使用中文版的浏览器访问http://www.google.com/时,就会返回中文版对应的资源,而使用英文版的浏览器访问时,则会返回英文版对应的资源。两者的URI是相同的,所以仅凭URI指定缓存的资源是相当困难的。若再下载过程中出现连接中断、再联机的情况,都会依照ETag值来指定资源。
强ETag和弱ETag值
- ETag中有强ETag值和弱ETag值之分。
强ETag值
-
强ETag值,不论实体发生多么细微的变化都会改变其值。
弱ETag值
-
弱ETag值只用于提示资源是否相同。只有资源发生了根本改变,产生差异时才会改变ETag值。这时,会在字段值最开始处附加W/。
Location
- 使用首部字段Location可以将相应接收方引导至某个与请求你URI位置不同的资源。
- 基本上,该字段会配合3xx:Redirection的响应,提供重定向的URI。
- 几乎所有的兰兰器在接收到包含首部字段Location的响应后,都会强制性地尝试对已提示的重定向资源的访问。
Proxy-Authenticate
- 首部字段Proxy-Authenticate会把由代理服务器所要求的认证信息发送给客户端。
- 它与客户端和服务器之前的HTTP访问认证的行为相似,不同之处在与其认证行为是在客户端与代理之间进行的。而客户端与服务器之间进行认证时,首部字段WWW-Authorization有着相同的作用。
Retry-After
- 首部字段Retry-After告知客户端应该在多久之后再次发送请求。主要配合状态码503 Service Unavailable响应,或3xx Redirect响应一起使用。
- 字段值可以指定为具体的日期时间,可以是创建响应后的秒数。
Server
-
首部字段Server告知客户端当前服务器上安装的HTTP服务器应用程序的信息不单单会标出服务器上的然健应用名称,还有可能包括版本号和安装时启用的可选项。
Vary
- 首部字段Vary可对缓存进行控制。源服务器会向代理服务器传达关于本地缓存使用方法的命令。
- 从代理服务器接收到源服务器返回包含Vary指定项的响应之后,若再要进行缓存,仅对请求中含有相同Vary指定首部字段的请求返回缓存。即使对相同资源发起请求,但由于Vary指定的首部字段不相同,因此必须要从源服务器重新获取资源。
WWW-Authenticate
- 首部字段WWW-Authenticate用于HTTP访问认证。它会告知客户端适用于访问请求URI所指定资源的认证方案和带参数提示的质询。状态码401 Unauthorized响应中,肯定带有首部字段WWW-Authenticate。
- 上述示例中,realm字段的字符串是为了辨别请求URI指定资源所受到的保护策略。
6.6 实体首部字段
-
实体首部字段是包含在请求报文和响应报文中的实体部分所使用的首部,用于补充内容的更新时间等与实体相关的信息。
Allow
- 首部字段Allow用于通知客户端能够支持Request-URI指定资源的所有HTTP方法。当服务器接收到不支持的HTTP方法时,会以状态码405 Method Not Allowed作为响应返回。与此同时,还会把所有能支持的HTTP方法写入首部字段Allow后返回。
Content-Encoding
-
首部字段Content-Encoding会告知客户端服务器对实体的主体部分选用的内容编码方式。内容编码是指在不丢失实体信息的前提下所进行的压缩。
- 主要采用以下4种内容编码的方式。
- gzip
- compress
- deflate
- identity
Content-Language
- 首部字段 Content-Language会告知客户端,实体主体使用的自然语言。
Content-Length
- 首部字段Content-Length表明了实体主体本分的大小。对实体主体进行内容编码传输时,不能再使用Content-Length首部字段。由于实体主体大小的计算方法略微复杂,所以在此不再展开。
Content-Location
- 首部字段Content-Location给出与报文主体部分相对应的UTI。和首部字段Location不同,Content-Location表示的是报文主体返回资源对应的URI。
- 比如,对于使用首部字段Accept-Language的服务器驱动型请求,当返回的页面内容与实际请求的对象不同时,首部字段Content-Location内会写明URI。
Content-MD5
- 首部字段Content-MD5是一串由MD5算法生成的值,其目的在于检查报文主体在传输过程中是否保持完整,以及确认传输到达。
- 对报文主体执行MD5算法获得的128位二进制数,再通过Base64编码后将结果写入Content-MD5字段值。由于HTTP首部无法记录二进制值,所以要通过Base64编码处理。为确保报文的有效性,作为接收方的客户端会对报文主体再执行一次相同的MD5算法。计算出的值与字段值作比较后,即可判断出报文主体的准确性。
- 采用这种方法,对内容上的偶发性改变是无从查证的,也无法检测出恶意篡改,那么同时意味着Content-MD5也可重新计算然后被篡改。所以处于接收阶段的客户端是无法一时到报文主体以及首部字段Content-MD5是已经被篡改过的。
Content-Range
- 针对范围请求,返回响应时使用的首部字段Content-Range,能告知哭护短作为响应返回的实体的哪个部分符合范围请求。字段值以字节为单位,表示当前发送部分及整个实体大小。
Content-Type
- 首部字段Content-Type说明了试题主体内对象的媒体类型。和首部字段Accept一样,字段值用type/subtype形式赋值。
Expires
- 首部字段Expires会将资源失效的日期告知客户端。缓存服务器在接收到含有首部字段Expires的响应后,会以缓存来应答请求,在Expires字段值指定的时间之前,响应的副本会一直被保存。当超过指定的时间后,缓存服务器在请求发送过来时,会转向源服务器请求资源。
- 源服务器不希望缓存服务器对资源缓存时,最好在Expires字段内谢日与首部字段Date相同的时间值。
- 但是,当首部字段Cache-Control有指定max-age指令时,比起首部字段Expires,会有限处理max-age指令。
Last-Modified
- 首部字段Last-Modified指明资源最终修改的时间。一般来说,这个值就是Request-URI指定资源被修改的时间。但类似使用CGI脚本进行动态数据处理时,改值有可能会变成数据最终修改时的时间。
6.7 为Cookie服务的首部字段
- 管理服务器与客户端之间状态的Cookie,虽然没有被编入标准化HTTP/1.1的RFC2616中,但在Web网站方面得到了广泛的应用。
- Cookie的工作机制是用户识别及状态管理。Web汪涵为了管理用户的状态会通过Web浏览器,把一些数据临时写入用户的计算机内。接着当用户访问该Web网站时,可通过通信方式取回之前存放的Cookie。
- 调用Cookie时,由于可校验Cookie的有效期,以及发送方的域、路径、协议等信息,所以正规发布的Cookie内的数据不会因来自为他Web站点和攻击者的攻击而泄漏。
- Cookie的规格标准文档有以下4种。
由网景公司颁布的规格标准
- 网景通信公司设计并开发了Cookie,并制定相关的规格标准。1994年前后,Cookie正式应用在网景浏览器中。目前最为普及的Cookie方式也是以此为基准的。
RFC2109
- 某公司尝试以独立技术对Cookie规格进行标准化统筹。原本的意图是想和网景公司制定的标准交互应用,可惜发生了微妙的差异。现在该标准已淡出了人们的视线。
RFC2965
- 为终结Internet Explorer浏览器与Netscape Navigator的标准差异而导致的浏览器战争,RFC2965内定了新的HTTP首部Set-Cookie2和Cookie2。
RFC6265
- 将网景公司制定的标准作为业界试试标准,重新定义Cookie标准后的产物。
- 目前使用最广泛的Cookie标准缺不是RFC中定义的任何一个。而是在网景公司制定的标准上进行扩展后的产物。
- 下面的表格内列举了与Cookie相关的首部字段说明。
Set-Cookie
- 当服务器准备开始管理客户端的状态时,会事先告知各种信息。
-
下面的表格列举了Set-Cookie的字段值
expires属性
- Cookie的expires属性指定浏览器可发送Cookie的有效期。
- 当省略expires属性时,其有效期仅限于维持浏览器回话时间段内,这通常限于浏览器应用程序被关闭之前。
- 另外,一旦Cookie从服务器端发送至客户端,服务器端就不存在可以显示删除Cookie的方法。但可通过覆盖已过期的Cookie,实现对客户端Cookie的实质性删除操作。
path属性
- Cookie的path属性可用于限制指定Cookie的发送范围的文件目录。不过另有办法可避开这项限制,看来对其作为安全机制的效果不能抱有期待。
domain属性
- 通过Cookie的domain属性指定的域名可做到与结尾匹配一致。比如,当指定example.com后,除example.com以外,www.example.com或www2.example.com等都可以发送Cookie;
- 因此,除了针对具体指定的多个域名发送Cookie之外,不指定domain属性显得更安全。
secure属性
- Cookie的secure属性用于限制Web页面仅在HTTP安全连接时,才可以发送Cookie。
- 发送Cookie时,指定secure属性的方法如下所示
- 以上例子仅当在https://www.example.com/安全连接的情况下才会进行Cookie的回收。也就是说,即使域名相同,HTTP://www.example.com/也不会发生Cookie回收行为。
- 当省略secure属性时,不论HTTP还是HTTPS,都会对Cookie进行回收。
HttpOnly属性
- Cookie的HttpOnly属性是Cookie的拓展功能,它使JavaScript脚本无法获得Cookie。其主要目的为防止跨站脚本攻击对Cookie的信息窃取。
- 发送指定HttpOnly属性的Cookie的方法如下所示:
- 通过上述设置,通常从Web页面内还可以对Cookie进行读取操作。但使用JavaScript的document.cookie就无法读取附加HttpOnly属性后的Cookie的内容了,因此,也就无法在XSS中利用JavaScript劫持Cookie了。
- 虽然是独立的拓展功能,但Internet Explorer 6 SPI以上版本等当下的主流浏览器都已经支持该拓展了,该拓展并非是为了防止XSS而开发的。
Cookie
- 首部字段Cookie会告知服务器,当客户端想获得HTTP状态管理支持时,就会在请求中包含从服务器接收到的Cookie。接收到多个Cookie时,同样可以以多个Cookie形式发送。
6.8 其他首部字段
- HTTP首部字段是可以自行拓展的。所以在Web服务器和浏览器的应用上,会出现各种非标准的首部字段。
- 接下来,我们就一些最为常见的首部字段进行说明
- X-Frame-Options
- X-XXS-Protection
- DNT
- P3P
X-Frame-Options
- 首部字段X-Frame-Options属于HTTP响应首部,用于控制网站内容在其他Web网站的Frame标签内的显示问题。其主要目的是为了防止点击劫持攻击。
- 首部字段X-Frame-Options有以下两个可指定的字段值。
- DENY:拒绝
- SAMEORIGIN:仅同源域名下的页面匹配时许可。支持该首部字段的浏览器有Internet Explorer 8、Firefox 3.6.9+、Chrome 4.1.249.1024+、Safari 4+和Opera 10.50+等。
- 能在所有的Web服务器端预先设定好X-Frame-Options字段值是最理想的状态
对apache2.conf的配置实例
X-XXS-Protection
- 首部字段X-XXS-Protection属于HTTP响应首部,它是针对跨站脚本攻击的一种对策,用于控制浏览器XSS防护机制的开关;
- 首部字段X-XXS-Protection可指定的字段值如下:
- 0:将XSS过滤设置成无效状态
- 1:将XSS过滤设置成有效状态
DNT
- 首部字段DNT属于HTTP请求首部,其中DNT是Do Not Track的简称,意为拒绝个人信息被收集,是表示拒绝被精准广告追踪的一种方法。
- 首部字段DNT可指定的字段值如下。
- 0:同意被追踪;
- 1:不同意被追踪;
- 由于首部字段DNT的工鞥具备有效性,所以Web服务器需要对DNT做对应的支持。
P3P
- 首部字段P3P属于HTTP响应首部,通过利用P3P技术,可以让Web网站上的个人隐私变成一种仅供程序可理解的形式,以达到保护用户隐私的目的。
- 要进行P3P的设定,需按一下操作步骤进行:
- 步骤1:创建P3P隐私
- 步骤2:创建P3P隐私对照文件后,保存命名在/w3c/p3p.xml
- 步骤3:从P3P隐私中新建Compactpolicies后,输出到HTTP响应中。
第七章 确保Web安全的HTTPS
7.1 HTTP的缺点
- 到现在为止,我们已了解到HTTP具有相当优秀和方便的一面,然而HTTP并非只有好的一面,食物皆具两面性,它也是有不足之处的。
- HTTP主要有这些不足,例如:
- 通信使用明文,内容可能会被窃听
- 不检验通信方的身份,因此有可能遭遇伪装
- 无法证明报文的完整性,所以有可能已遭篡改
- 这些问题不仅在HTTP上出现,其他未加密的协议中也会存在这类问题。
- 除此之外,HTTP本身还有很多缺点。而且,还有像某些特定的Web服务器和特定的Web浏览器在实际应用中存在的不足,另外,用Java和PHP等变成语言开发的Web应用也可能存在安全漏洞。
通信使用明文可能会被窃听
- 由于HTTP本身不具备加密的功能,所以也无法做到对通信整体进行加密。即,HTTP报文使用明文方式发送。
TCP/IP是可能被窃听的网络
- 如果要问为什么通信时不加密是一个缺点,这是因为,按TCP/IP协议族的工作机制,通信内容在所有的通信线路上都有可能遭到窥视。
- 所谓互联网,是由能联通到全世界的网络组成的。无论世界哪个角落的服务器在和哭护短通信时,在此通信线路上的某些网络设备、光缆、计算机等都不可能是个人的私有物,所以不排除某个环节中遭到恶意窥视的行为。
- 即使已经过加密处理的通信,也会被窥视到通信内容,这点和未加密的通信是相同的。只是说如果通信经过加密,就有可能让人无法皮杰报文信息的含义,但加密处理后的报文信息本身还是会被看到的。
- 窥视相同段上的通信并非难事。只需要手机在互联网上流动的数据包就行了。对于收集来的数据包的解析工作,可交给那些抓包或嗅探器工具。
- 下面的图片示例就是被广泛使用的抓包工具Wireshark。它可以获取HTTP协议的请求和响应的内容,并对其进行解析。
- 像使用GET方法发送请求、响应返回了200 OK,查看HTTP响应报文的全部内容等一系列的事情都可以做到。
加密处理防止被窥视
- 在目前大家正在研究的如何防止窃听保护信息的几种对策中,最为普及的就是加密技术。加密的对象可以有这么几个。
通信的加密
- 一种方式就是将通信加密。HTTP协议中没有加密机制,但可以通过和SSL或TLS的组合使用,加密HTTP的通信内容。
- 用SSL建立安全通信线路之后,就可以在这条线路上进行HTTP通信了。与SSL组合使用的HTTP呗称为HTTPS或HTTP over SSL。
内容的加密
- 还有一种将参与通信的内容本身加密的方式。由于HTTP协议中没有加密机制,那么就对HTTP协议传输的内容本身加密。即把HTTP报文里所含的内容进行加密处理。
- 在这种情况下,客户端需要对HTTP报文进行加密处理后再发送请求。
- 为了做到有效的内容加密,前提是要求客户端和服务器同事具备加密和解密机制。主要应用在Web服务中。有一点必须引起注意,由于该方式不同于SSL或TLS将这个通信线路加密处理,所以内容仍有被篡改的奉献。
不验证通信方的身份就可能遭遇伪装
- HTTP协议中的请求和响应不会对通信方进行确认。也就是说存在“服务器是否就是发送请求中HRI真正指定的主机,返回的响应是否真的返回到实际提出请求的客户端”等类似问题。
任何人都可发起请求
- 在HTTP协议通信时,由于不存在确认通信方的处理步骤,任何人都可以发起请求。另外,服务器只要接收到请求,不管对方是谁都会返回一个相应。
- HTTP协议的实现本身非常简单,不论是谁发送过来的请求都会返回响应,因此不确认通信方,会存在以下各种隐患。
- 无法确定请求发送至目标的Web服务器是否是按真是意图返回响应的那台服务器,有可能是已伪装的Web服务器。
- 无法确定响应返回到的客户端是否是按真是意图接收响应的那个客户端。有可能是已伪装的客户端。
- 无法确定正在通信的对方是否具备访问权限。因为某些Web服务器上保存着重要的信息,只想发给特定用户通信的权限。
- 无法判定请求是来自何方、出自谁手。
- 即使是无意义的请求也会照单全收。无法阻止海量请求下的DoS攻击。
查明对手的证书
- 虽然使用HTTP协议无法无额定通信方,但如果使用SSL则可以。SSL不仅提供加密处理,而且还使用了一种被称为证书的手段,可用于确定方。
- 证书由值得信任的第三方机构颁发,用以证明服务器和客户端是实际存在的。另外,伪造证书从技术角度来说是异常困难的一件事,所以只要能够确认通信方持有的证书,即可判断通信方的真实意图。
- 通过使用证书,以证明通信方就是意料中的服务器。这对使用者个人来讲,也减少了个人信息泄漏的危险性。
- 另外,客户端持有证书即可完成个人身份的确认,也可用于对Web网站的认证环节。
无法证明报文完整性,可能已遭篡改
- 所谓完整性是指信息的准确度。若无法证明其完整性,通常也就意味着无法判断信息是否准确。
接收到的内容可能有误
- 由于HTTP协议无法证明通信的报文完整性,因此,在请求或响应送出之后直到对方接收之前的这段时间内,即使请求或响应的内容遭到篡改,也没有办法获悉。
- 换句话说,没有任何办法确认,发出的请求/响应和接收到的请求/请求是前后相同的。
- 比如,从某个Web网站上下载内容,是无法确定客户端下载的文件和服务器上存放的文件是否前后一致的。文件内容在传输途中可能已经被篡改为其他的内容。即使内容真的已改变,作为接收方的客户端也是觉察不到的。
- 像这样,请求或响应再传输途中,遭攻击者拦截并篡改内容的攻击称为中间人攻击。
如何防止篡改
- 虽然是使用HTTP协议确定报文完整性的方法,但事实上并不编辑、可靠。其中常用的是MD5和SHA-1等散列值校验的方法,已经用来确认文件的数组签名方法。
- 提供文件下载服务的Web网站也会提供相应的以PGP创建的数字签名及MD5算法生成的散列值。PGP是用来证明创建文件的数字签名,MD5是由单项函数生成的散列值。不论使用哪一种方法,都需要操纵客户端的用户本人亲自检查验证下载的文件是否就是原来服务器上的文件。浏览器无法自动帮用户检查。
- 可惜的是,用这些方法也依然无法百分百保证确认结果正确。因为PGP和MD5本身呗改写的话,用户就没有办法意识到的。
- 为了有效防止这些弊端,有必要使用HTTPS。SSL提供认证和加密处理及摘要功能。仅靠HTTP确保完整性是非常困难的,因此通过和其他协议组合使用来实现这个目标。
7.2 HTTP + 加密 + 认证 + 完整性保护 = HTTPS
HTTP加上加密处理和认证以及完整性保护后即是HTTPS
- 如果在HTTP协议通信过程中使用未经加密的明文,比如在Web页面中输入信用卡号,如果这条通信线路遭到窃听,那么信用卡号就暴露了。
- 另外,对于HTTP来说,服务器也好,客户端也好,都是没有办法确认同新方的。因为很有可能并不是和原本预想的同新方在实际通信。并且还需要考虑到接收到的报文在通信途中已经遭到篡改这一可能性。
- 为了统一解决上述这些问题,需要在HTTP再加上加密处理和认证等机制。我们把增加了加密及认证机制的HTTP称为HTTPS。
- 经常会在Web的登录页面和购物结算界面等使用HTTPS通信,使用HTTPS通信时,不再用http://,而是改用http://。另外,当浏览器访问HTTPS通信有效的Web网站时,浏览器的地址栏内会出现一个带锁的标记。对HTTPS通信有效的Web网站时,浏览器的地址栏内出现一个带锁的标记。对HTTPS的显示方式会因浏览器的不同而有所改变。
HTTPS是身披SSL外壳的HTTP
- HTTPS并非是应用层的一种新协议。只是HTTP通信接口部分用SSL和TLS协议代替而已。
- 通常,HTTP直接和TCP通信。当使用SSL时,则演变成先和SSL通信,再由SSL和TCP通信了。简言之,所谓HTTPS,其实就是身披SSL协议这层外壳的HTTP。
- 在采用SSL后,HTTP就拥有了HTTPS的加密、证书和完整性保护这些功能。
- SSL是独立于HTTP的协议,所以不光是HTTP协议,其他运行在应用层的SMTP和Telnet等协议均可配合SSL协议使用。可以说SSL是当今世界上应用最为广泛的网络安全技术。
相互交换秘钥的公开秘钥加密技术
- 在堆SSL进行讲解之前,我们先来了解一下加密方法。SSL采用一种叫做公开秘钥加密的加密处理方式。
- 近代的加密方法中加密算法是公开的,而秘钥却是保密的。通过这种方式得以保持加密方法的安全性。
- 加密和解密都会用到密钥。没有密钥就无法对棉麻解密,翻过来说,任何人只要持有密钥就能解密了。如果密钥被攻击者获得,那加密也就失去了意义。
共享密钥加密的困境
- 加密和解密同用一个密钥的方式称为共享密钥加密,也被叫做对称密钥加密
- 以共享密钥方式加密时必须将密钥也发给对方。可究竟怎样才能安全地转交?在互联网上转发密钥时,如果通信被监听那么密钥就可会落入攻击者之手,同时也就失去了加密的意义。另外还得设法安全地保管接收到的密钥。
使用两把密钥的公开密钥加密
- 公开密钥加密方式很好地解决了共享密钥加密的困难。
- 公开密钥加密使用一对非对称的密钥。一把叫做私有密钥,另一把叫做公开密钥。顾名思义,私有密钥不能让其他任何人知道,而公开密钥则可以随意发布,任何人都可以获得。
- 使用公开密钥加密方式,发送密文的一方受用对方的公开密钥进行加密处理,对方收到被加密的信息后,再使用自己的私有密钥进行解密。利用这种方式,不需要发送用来解密的私有密钥,也不必担心密钥被攻击者窃听而盗走。
- 另外,要想根据密文和公开密钥,恢复到信息原文是异常困难的,因为解密过程就是在对离散对数进行求值,这并非轻而易举就能办到。退一步讲,如果能对一个非常大的证书做到快速地因式分解,那么密钥破解还是存在希望的。但就目前的技术来看是不太现实的。
HTTPS采用混合加密机制
- HTTPS采用共享密钥加密和公开密钥加密两者并用的混合加密机制。若密钥能够实现安全交换,那么有可能会考虑仅使用公开密钥加密来通信。但是公开密钥加密与共享密钥加密相比,其处理速度要慢。
- 所以应充分利用两者各自的优势,将多种方法组合起来用于通信,在交换密钥环节使用公开密钥加密方式,之后的简历通信交换报文阶段则使用共享密钥加密方式。
证明公开秘钥正确性的证书
- 遗憾的是,公开密钥加密方式还是存在一些问题的。那就是无法证明公开密钥本身就是货真价实的公开密钥。比如,正准备和某台服务器建立公开密钥加密方式下的通信时,如果证明收到的公开密钥就是原本预想的那台服务器发行的公开密钥。或许在公开密钥传输途中,真正的公开密钥已经被攻击者替换掉了。
- 为了解上述问题,可以使用由数字证书认证记否和其相关机关颁发的公开密钥证书。
- 数字证书认证机构处于客户端与服务器双方都可信赖的第三方机构的立场上。威瑞信就是其中一家非常有名的数字证书认证机构,我们来接胡搜啊一下数字证书认证机构的业务流程。首先,服务器的运营人员向数字证书认证机构提出公开密钥的请求。数字证书认证机构在判明提出申请者的身份之后,会对已申请的公开密钥做数字签名,然后分配这个已签名的公开木遥,并将该公开密钥放入公钥证书后绑定在一起。
- 服务器会将这份由数字证书认证机构颁发的公钥证书发送给客户端,以进行公开密钥加密方式通信。公钥证书也可叫做数字证书或直接成为证书。
- 接到证书的客户端可使用数字证书认证机构的公开密钥,对那张证书上的数字签名进行验证,一旦验证通过,客户端便可明确两件事:一,认证服务器的公开密钥的是真实有效的数字证书认证机构。二,服务器的公开密钥是值得信赖的。
- 此处认证机构的公开密钥必须安全地转交给客户端。使用通信方式时,如何安全转交是一件很苦难的事,因此,多数浏览器开发商发布版本时,会事先在内部植入常用认证机关的公开密钥
可证明组织真实性的EV SSL证书
- 证书的一个作用是用来证明作为通信一方的服务器是否规范,另外一个作用是可确认对方服务器背后运营的企业是否真实存在。拥有改特性的证书就是EV SSL证书。
- EV SSL证书是基于国际标准的认证知道方针办法的证书。其严格规定了对运营组织是否真实的确认方针,因此,通过认证的Web网站能够获得更高的认可度。持有EV SSL证书的Web网站的浏览器地址栏处的背景色是绿色的,从视觉上就能一眼辨别出。而且在地址栏的左侧显示了SSL证书中记录的组织名称以及办法证书的认证机构的名称;
-
上述机制的愿意图是为了防止用户被钓鱼攻击,但就效果上来讲,还得打一个问号。
用以确认客户端的客户端证书
- HTTPS中还可以使用客户端证书。以客户端证书进行客户端认证,证明服务器正在通信的对方始终是预料之内的客户端,其作用跟服务器证书如出一辙。
- 但客户端证书扔存在几处问题点。其中的一个问题点是证书的获取及法本。
- 想获取证书时,用户得自行安装客户端证书。但由于客户端证书是要付费购买的,且没涨生疏对应到每位用户也就以为着需支付和用户数对等的费用。另外,要让知识层次不同的用户们自行安装证书,这件事本身也充满了各种挑战。
- 现状是,安全性极高的认证机构可颁发客户端证书但仅用于特殊用途的业务,比如那些可制成客户端证书支出费用的业务。
- 客户端证书存在的另一个问题点是,客户端证书毕竟只能用来证明客户端实际存在,儿不能用来证明用户本人的真实有效性,也就是说,只要获得了安装有客户端证书的计算机的使用权限,也就意味着同时拥有了客户端证书的使用权限。
认证机构信誉第一
- SSL机制中介入认证机构之所以可行,是因为建立在其信用绝对可靠这一大前提下的。然而,2011年7月,荷兰的一家名叫DigiNotar的认证机构曾遭黑客不法入侵,颁布了google.com和witter.com等网站的伪造证书时间。这一时间从根本上撼动了SSL的可信度。
- 因为伪造证书上有正规认证机构的数字签名,所以浏览器会判定该证书是正当的。当伪造的证书被用做服务器伪装之时,用户根本无法察觉到。
- 虽然存在可将证书无效化的证书吊销列表机制,以及从客户端阐述根证书颁发机构的对策,但是距离生效还需要一段时间,而在这段时间内,到底会有多少用户的利益蒙受损失不得而知了。
由自认证机构颁发的认证称为自签名证书
- 如果使用OpenSSL这套开源程序,每个人都可以构建一套属于自己的认证机构,从而自己给自己颁发服务器证书,但该服务器证书在互联网上不可作为证书使用,似乎没什么帮助。
- 独立构建的认证机构叫做自认证记否,由自认证机构颁发的“无用”证书也被戏称为自签名证书。
-
浏览器访问该服务器时,会显示“无法确认连接安全性”或“该网站的安全证书存在问题”等警告消息。
- 由自认证机构颁发的服务器证书之所以不起作用,是因为它无法消除伪装的可能性,自认证机构能够产生的作用顶多也就是自己对外宣称“我是**”的这种程度。即使采用自签名证书,通过SSL加密之后,可能偶尔还会看见通信处在安全状态的提示,可那也是有问题的。因为就算加密通信,也不能排除正在和已经过伪装的假服务器保持通信。
- 值得信赖的第三方机构介入认证,才能让已植入在浏览器内的认证机构颁布的公开密钥发挥作用,并借此证明服务器的真实性。
- 中级认证机构的证书可能会变成自认证证书
- 多数浏览器内预先已植入备受新来的认证机构的证书,但也有一小部分浏览器会植入中级认证机构的证书;
- 对于中级认证机构颁布的服务器证书,某些浏览器会以正规的证书来对待,可有的浏览器会当做自签名证书。
HTTPS的安全通信机制
-
HTTPS的通信步骤
- 步骤1:
- 客户端通过发送Client Hello报文开始SSL通信。报文中包含客户端支持的SSL的指定版本、加密组件列表。
- 步骤2:
- 服务器可进行SSL通信时,会以Server Hello报文作为应答。和客户端一样,在报文中包含SSL版本以及加密组件。服务器的加密组件内容是从接收到的客户端加密组件内筛选出来的。
- 步骤3:
- 之后服务器发送Certificate报文.报文中包含公开密钥证书.
- 步骤4:
- 最后服务器发送Server Hello Done报文通知客户端,最初剪短的SSL握手协商部分结束。
- 步骤5:
- SSl第一次握手结束之后,客户端以Xlient Key Exchange报文作为回应。报文中包含通信加密中使用的一种被称为Pre-master secret的随机密码串。该报文已用步骤3中的公开密钥进行加密。
- 步骤6:
- 接着客户端继续发送Change Cipher Spec报文。该报文会提示服务器,在此报文之后的通信会采用Pre-master secret密钥加密;
- 步骤7:
- 客户端发送Finished报文。该报文包含连接至今全部报文的整体校验值。这次握手协商是否能够成功,要以服务器是否能够正确解密改报文作为判定标准。
- 步骤8:
- 服务器同样发送Change Cipher Spec报文。
- 步骤9:
- 服务器同样发送Finished报文。
- 步骤10:
- 服务器和客户端的Finished报文交换完毕之后,SSL连接就算简历完成。当然,通信会受到SSL的保护。从此处开始进行应用层协议的通信,即发送HTTP请求。
- 步骤11:
- 应用层协议通信,即发送HTTP响应。
- 步骤12:
- 最后由客户端断开连接。断开连接时,发送close_notify报文。上图做了一些省略,这步之后再发送TCPFIN报文来关闭与TCP的通信。在以上流程中,应用层发送数据时会附加一种叫做MAC的报文摘要。MAC能够查知报文是否遭到篡改,从而保护报文的完整性。
-
下面是对整个流程的图解,途中说明了从仅使用服务器端的公开密钥证书简历HTTPS通信的整个过程。
SSL和TLS
- HTTPS使用SSL和TLS这两个协议。
- SSL技术最初是由浏览器开发商网景通信公司率先倡导的,开发过SSL3.0之前的版本。目前主导权已转移到IETF的手中。
- IETF以SSL3.0为基准,后又制定了TLS1.0、TLS1.1和TLS1.2.TSL是以SSL为原型开发的协议,有时会统一称该协议为SSL。当前主流的版本是SSL3.0和TLS1.0.
- 由于SSL1.0版本在设计之初被发现出了问题,就没有实际投入使用≥SSL2.0也被发现存在问题,所以很多浏览器直接飞出了改协议版本。
SSL速度慢吗
- HTTPS也存在一些问题,那就是当使用SSL时,他的处理速度会变慢。
- SSL的慢分两种。一种是指通信慢。另一种是指由于大量消耗CPU及内存等资源,导致处理速度变慢。
- 和使用HTTP相比,网络负载可能会变慢2到100倍。出去和TCP连接、发送HTTP请求-响应以外,还必须进行SSL通信,因此整体上处理通信量不可避免会增加。
- 另一点是SSL必须进行加密处理。在服务器和客户端都需要进行加密和解密的运算处理。因此从结果上讲,比起HTTP会更多地消耗服务器和客户端的硬件资源,导致负载增强。
- 针对速度变慢这一问题,并没有根本性的解决方案,我们会使用SSL加速器这种硬件来改善该问题。该硬件为SSL通信专用硬件,相对软件来讲,能够提高数倍SSL的计算速度。仅在SSL处理时发挥SSL加速器的功效,以分担负载。
为什么不一直使用HTTPS
- 既然HTTPS那么安全可靠,那为何所有的Web网站不一直使用HTTS?
- 其中一个原因是,因为与纯文本通信相比,加密通信会消耗更多的CPU及内存资源。如果每次通信都加密,会消耗相当多的资源,平摊到一台计算机上时,能够处理的请求数量必定也会随之减少。
- 因此,如果是非敏感信息则使用HTTP通信,只有在包含个人信息等敏感数据时,才利用HTTPS加密通信。
- 特别是每当那些访问量较多的Web网站在进行加密处理时,他们所承担着的负载不容小窥。、在进行加密处理时,并非对所有内容都进行加密处理,而是仅在那些需要信息隐藏时才会加密,以节约资源。
- 除此之外,想要节约购买证书的开销也是原因之一。
- 要进行HTTPS通信,证书是必不可少的。而使用的证书必须向认证机构购买,证书价格可能会格局不同的认证机构略有不同。
第八章 确定访问用户身份的认证
8.1 何为认证
- 计算机本身无法判断坐在显示器前的使用者的身份。进一步说,也无法确认网络的那头究竟有谁。可见,为了弄清究竟是谁在访问服务器,就得让对方的客户端自报家门。
- 可是,就算正在访问服务器的对方声称自己的ueno,身份是否属实这点却也无从谈起。为确认ueno本人是否真的具有访问系统的权限,就需要核对“登录者本人才知道的信息”、“登录者本人才会有的信息”;
- 核对的信息通常是指一下这些:
- 密码:只有本人才会知道的字符串信息。
- 动态令牌:仅限本人持有的设备内显示的一次性密码;
- 数字证书:仅限本人持有的信息。
- 生物认证:指纹和虹膜等本人的生理信息。
- IC卡等:仅限本人持有的信息
- 但是,即便对方是假冒的用户,只要能通过用户验证,那么计算机就会默认是出自本人的行为。因此,掌控机密信息的密码绝不能让他人得到,更不能轻易地就被破解出来。
- HTTP使用的认证方式
- HTTP/1.1使用的认证方式如下所示。
- BASIC认证(基本认证)
- DIGEST认证(摘要认证)
- SSL客户端认证
- FormBase认证(基于表单认证)
- 此外,还有Windows统一认证(Keberos认证、NTLM认证);
- HTTP/1.1使用的认证方式如下所示。
8.2 BASIC认证
- BASIC认证(基本认证)是从HTTP/1.0就定义的认证方式。即便是现在仍有一部分的网站会使用这种认证方式。是Web服务器与通信客户端之前进行的认证方式。
BASIC认证的认证步骤
-
步骤1:
- 当请求的资源需要BASIC认证时,服务器会随时状态码401 Authorization Required,返回带WWW-Authenticate首部字段的响应。该字段内包含认证的方式(BASIC)及Request-URI安全域字符串。
-
步骤2:
-
接收到状态码401的客户端为了通过BASIC认证,需要将用户ID及密码发送给服务器。发送的字符串内容是由用户ID和密码构成,两者中间以冒号(:)连接后,再经过Base64编码处理。假设用户ID未guest,密码是guest,连接起来就会形成guest:guest这样的字符串。然后经过Base64编码,最后的结果即是Z3Vlc3Q6Z3VQ=。把这串字符串写入首部字段Authorization后,发送请求。当用户代理为浏览器时,用户仅需输入用户ID和密码即可,之后,浏览器会自动完成到BASE64编码的转换工作。
-
-
步骤3:
- 接收到包含首部字段Authorization请求的服务器,会对认证信息的正确性进行验证。如验证通过,则返回一条包含Requset-URI资源的响应
- BASIC认证虽然采用Base64编码方式,但这不是加密处理。不需要任何附加信息即可对其解码。换言之,由于明文解码后就是用户ID和密码,在HTTP等非加密通信的线路上进行BASIC认证的过程中,如果被人窃听,被盗的可能性极高。
- 另外,除此之外想再进行一次BASIC认证时,一般的浏览器却不乏实现认证注销操作,这也是问题之一。
- BASIC认证使用上不够便捷灵活,且达不到多次Web往回走哪期望的安全性等级,因此它并不常用。
8.3 DIFEST认证
为弥补BASIC认证存在的弱点,从HTTP/1.1起就有了DIGEST认证。DIGEST认证同样使用质询/响应的方式,但不会像BASIC认证那样直接发送明文密码。
-
所谓质询响应方式是指,一开始一方会发送认证要求给另一方,接着使用从另一方那接收到的质询码计算生成响应码。最后将响应码返回给对方进行认证的方式。
因此方法给对方的只是响应摘要及由质询码产生的计算结果,所以比起BASIC认证,面膜企鹅楼的可能性就降低了。