一.简述HTTP
URI
客户端向服务器发起请求访问资源,服务器响应时,Web服务器会为所有的Http对象数据附加一个MIME类型.如下图
URI 统一资源标识符(URL和URN是URI的两种类型)
URL 统一资源定位符
标准格式包含三部分
“方案://服务器位置/路径”
(1)方案(scheme) 说明访问资源所使用的协议类型(比如http://)
(2)第二部分是服务器的位置,因特网地址 (比如www.baidu.com)
(3)其余部分指定服务器上的某个资源,资源路径(比如/img.png)
URN 统一资源名
是作为特定内容的唯一名称使用的,与目的资源所在地无关.
方法
客户端发起服务器返回的过程
HTTP版本
HTTP1.0和HTTP1.1
常见的方案
二.HTTP报文
术语:
流入:请求报文流入源端服务器
流出:报文从源端服务器流出到用户Agent代理(Agent代理是所有能代替用户发送请求的应用程序,比如web浏览器)
上游 下游:所有的报文都会像河水一样流动,不管是请求报文还是响应报文,都会像下游流动.所有报文的发送者都在接收者的上游.
报文的格式
任何报文都由三个部分组成:起始行(请求报文称为请求行,响应报文中称为响应行),首部,和主体部分如下图
下面展示了请求报文和响应报文的组成,和一组假想的请求报文和响应报文作文参照
方法
并不是每个服务器都实现了所有的方法,比如一台服务器要与HTTP1.1兼容,那么只要为其资源实现GET方法和HEAD方法就可以了
HEAD方法
HEAD方法在服务器响应中只返回首部,不会返回实体的主题部分,这就允许客户端在未获取实际资源的情况下,对资源的首部进行检查.比如可以:
- 在不获取资源的情况下了解资源的情况(比如判断其类型)
- 通过查看响应中的状态码,看看某个对象是否存在
- 通过查看首部,测试资源是否被修改了
TRACE方法
可恶端发起一个请求时,这个请求可能要穿过防火墙,代理,网关或其他一些应用程序.每个中间节点都可能会修改原始的HTTP请求.TRACE方法允许客户端在最终将请i去发送给服务器时,蓝看他办成了什么样子
OPTIONS方法
OPTIONS方法请求web服务器告知其支持的各种功能,可以询问服务器通常支持哪些方法,或者对某些特殊资源支持哪些方法.下图显示了一个使用OPTIONS方法的请求
状态码
100-199信息性状态码
100 Continue目的时对这样的情况进行优化:HTTP客户端应用程序有一个尸体的主体部分想要发送给服务器,但是希望在发送之前查看一下服务器是否会接受这个实体.
200-299成功状态码
300-399重定向状态码
重定向状态码要么告知客户端使用替代位置来访问他们所感兴趣的资源,要么就提供一个体态的响应而不是资源的内容.如果资源已经被移动,可以发送一个重定向状态码和一个可选的Location首部来告知客户端资源已被一走,以及现在可以在哪里找到它,这样浏览器可以在不打扰使用者的情况下,透明的转入新的位置.如下
可以通过某些重定向状态码对本地的副本进行验证,确认是否源服务端上的资源被修改过,如下请求
从下面列出所有的重定向状态码
400-499客户端错误状态码
500-599状态码
HTTP首部
HTTP规范定义了几种首部字段,应用程序亦可以随意发明自己所用的首部.分为以下几类
通用首部
既可以出现在请求报文中,也可以出现在响应报文中
请求首部
(1)Accept首部
Accept首部为客户端提供了一种将其想要什么形式的内容告知服务器的方式.Accept首部会使连接的两端都收益,客户端会得到他们想要的内容,服务器就可以根据这些信息来决定发送的内容,不会浪费其时间和贷款来发送客户端无法使用的东西.
(2)条件请求首部
有时客户端希望为其请求加上某些限制,就可以通过使用条件请求头部的方式,要求服务器在对请求进行响应之前,确保某个条件为真.
(3)安全请求首部
质询/响应认证.这种机制要求客户端在获取特定的资源之前,先对自身进行认证,这样可以使事务安全一些.
(4)代理请求首部
响应首部
(1)协商首部
如果资源有多种表示方法,比如如果服务器上有某文档的法语和德语稿,HTTP1/1.1可以为服务器和客户端提供对资源进行协商的能力.
(2)安全响应首部
前面提到的质询/响应机制的响应侧.
实体首部
描述实体的长度和内容,或者资源自身
在请求和响应报文中都可能包含实体部分,所有这两中类型的报文都可能出现这些首部
(1)内容首部
与实体内容有关的特定信息,说明了其类型尺寸以及处理它所需要的其他有用信息.比如web浏览器可以通过查看返回的内容类型,得知如何显示对象.
(2)实体缓存首部
通用的缓存首部说明了如何或什么时候进行缓存,实体的缓存首部提供了与被缓存实体有关的信息.比如验证已缓存的资源副本是否仍然有效所需的信息,以及更好的估计已缓存的资源合适失效所需的线索.
扩展首部
版本0.9的报文
版本0.9请求中只包含方法和URL,响应中只包含实体,他没有版本信息,没有状态码或原因短语也没有首部
三.连接
每个TCP段都是由IP分组承载,从一个IP地址发送到另一个IP地址的,每个IP分组中都包括:
- 一个IP分组首部
- 一个TCP段首部
- 一个TCP数据块
任何时候计算机都可以有几条tcp连接处于打开状态,tcp是通过端口来保持这些连接的正确运行的.
TCP连接是通过四个值来辨别的,<源IP地址,源端口号,目的IP地址,目的端口号>这四个值一起唯一定义了一条连接
TCP性能
HTTP事务的时延
主要有以下几种原因:
(1)客户端首先要根据url确定web服务器的ip地址.(如果最近访问过,则dns缓存可以很快的解析出来)
(2)客户端向服务器发一条tcp连接请求.每条tcp连接都会有连接建立时延
(3)连接建立起来,客户端会通过新建立的tcp管道来发送http请求,web服务器会读取请求报文并处理.因特网传输请求报文,以及服务器处理请求报文都需要时间.
(4)web服务器回送http响应报文也需要时间.
性能聚焦区
常见的tcp相关时延如下
- tcp连接建立握手
- tcp慢启动拥塞控制
- 数据聚集的Nagle算法
- 用于捎带确认的tcp延迟确认算法
- TIME_WAIT时延和端口耗尽
延迟确认
每个段的接收者收到完好的段时都会向发送者回送小的确认分组,如果发送者没有在指定的窗口时间内收到确认信息,发送者就认为分组已经被破坏并重发数据.
由于确认报文很小,所以tcp允许在发往相同方向的输出数据分组中对其进行”捎带”.为了增加确认报文找到同向传输数据分组的可能性,很多tcp栈都实现了一种”延迟确认”算法,延迟确认算法会在一个特定的窗口时间内将输出的确认存放在缓冲区中,以寻找能够捎带它的输出数据分组,如果在那个时段内没有输出数据分组,就将确认信息放在单独的分组中传送.
TCP慢启动
TCP连接会随着时间进行自我”调谐”,起初会限制连接的最大速度.如果数据成功传输,会随着时间的推移提高传输的速度.这被称为TCP慢启动,用于防止因特网的突然过载和拥塞.
Nagle算法
TCP有一个数据流接口,应用程序可以通过它将任意尺寸的数据放入TCP栈中,但是每个tcp段中都至少装载了40个字节的标记和首部,所以如果TCP发送了大量的包含少量数据的分组,网络的性能就会严重下降.
Nagle算法鼓励发送全尺寸的段,只有当所有其他分组都被确认后,nagle算法才允许发送非全尺寸的分组.
nagle算法会引发几种HTTP性能的问题.首先,小的HTTP报文可能无法填满一个分组,可能会因为等待那些永远不会到来的额外数据而产生时延.其次nagle算法与延迟确认之间的监护存在问题—nagle算法会阻止数据的发送,直到有确认分组抵达为止,但确认分组自身会被延迟确认算法延迟.
http应用程序常常会在自己的栈中设置参数TCP_NODELAY来禁用nagle算法.
串行连接
缺点
1tcp的性能时延会叠加起来.比如有一个包含了3个嵌入图片的web页面.如果每个事务都要一条新的连接,那么连接时延和慢启动时延就会叠加起来.而且加载一幅图片时,页面上其他地方没有动静也会让人觉得速度很慢.
2有些浏览器再对象加载完毕前无法获知对象的尺寸,无法决定将对象放在什么位置,所以在加载了足够多的对象之前,无法再屏幕上显示任何内容.用户面对的是一个空白的屏幕.
并行连接
如上图所示即为并行连接请求和响应的过程.
即使并行连接的速度可能会更快,但是不一定总是更快.客户端的网络带宽不足时,一个连接到速度较快的服务器上的HTTP事务就会很容易地耗尽所有可用的带宽.如果并行加载多个对象,每个对象都去竞争这有限的带宽,每个对象都会以较慢的速度按比例加载,这样带来的性能提升就非常小
而且打开大量连接会消耗很多内存资源,从而引发自身性能的问题.一百个用户同时发出申请,每个用户打开一百个连接,服务器就要负责处理10000个连接,这会造成服务器性能严重下降.
实际上,浏览器确实使用了并行连接,但是会将连接的总数限制为一个较小的值.
缺点:
- 每个事务都会打开一条新的连接,会耗费时间和带宽
- 由于tcp慢启动的特性,每条连接的性能都会有所降低
- 可打开的并行连接数量实际上是有限的
持久连接
TCP慢启动
TCP数据传输会随着时间进行自我调谐,起初会限制连接的最大速度,如果数据成功传输,会随着时间的推移提高传输的速度.这种调谐被成为TCP慢启动,用于防止因特网的突然过载和拥塞.所以新连接的传输速度会比已经交换过一定量数据的连接慢一些.
在事务处理结束之后仍然保持在打开状态的TCP连接被称为持久连接.重用已对目标服务器打开的空闲持久连接,就可以避开缓慢的连接建立阶段.而且已经打开的连接还可以避免慢启动的拥塞适应阶段,以便更酷爱的进行数据的传输.
HTTP/1.0+keep-alive连接
实现HTTP/1.0 keep-alive连接的客户端可以通过包含Connection:Keep-alive首部请求将一条连接保持在打开状态.
如果服务器愿意为下一条请求将连接保持在打开状态,就在响应中包含相同的首部。如果响应中没有Connection: Keep-Alive首部,客户端就认为服务器不支持keep-alive,会在发回响应报文之后关闭连接。
Keep-Alive选项
可以用Keep-Alive通用首部中指定的,由都好分割的选项来调节keep-alive的行为.
- 参数timeout是在Keep-Alive响应首部发送的,他估计了服务器希望将连接保持在活跃状态的时间,这并不是一个承诺值
- 参数max是在Keep-Alive响应首部发送的,他估计了服务器还希望为多少个事务保持此连接的活跃状态,不是承诺值
Keep-Alive首部完全是可选的,但只有在提供Connection: Keep-Alive时才能使用它。这里有个Keep-Alive响应首部的例子,这个例子说明服务器最多还会为另外5个事务保持连接的打开状态,或者将打开状态保持到连接空闲了2分钟之后。
1 | connection: Keep-Alive |
Keep-Alive和哑代理
1Connetion首部和盲中继
问题出现在代理上,尤其是那些不理解Connection首部,而且不知道在沿着转发链路将其发送出去之前,应该将该首部删除的代理.下图显示了这种情形
上图中哑代理收到了这条HTTP请求,但是不理解Connection首部,因此原封不动的发给服务器.但是Connection首部是个逐跳首部,只适用于单条传输链路.服务器收到带有Connection:Keep-Alive首部的请求,会以为代理希望进行持久连接,回送了Connection首部,所以此时服务器认为他在与代理进行keep-alive对话,然而代理却一无所知.代理将收到的所有数据返回给客户端,然后等待源服务器管理连接,但是源服务器认为会和代理进行keep-alive对话,不回去关闭连接,这样,代理就会挂在哪里等待连接的关闭,客户端看到后会认为代理同意进行keep-alive对话,会向代理发送另一条请求,而代理不认为同一条连接上会有其他请求到来就会忽略.
这种错误的通信方式会使浏览器一直处于挂起状态,直到客户端或服务器将连接超时并将其关闭为止.
为避免此类代理通信问题的发生,现代的代理都绝不能转发connection首部和所有名字出现在Connection值中的首部。因此,如果一个代理收到了一个Connection: Keep-Alive首部,是不应该转发connection首部,或所有名为Keep-Alive的首部的。
HTTP/1.1持久连接
与HTTP/1.0的keep-alive连接不同,HTTP/1.1持久连接在默认情况下是激活的,除非特别指明,否则HTTP/1.1假定所有链接都是持久的.
HTTP/1.1客户端假定在收到响应后,除非响应中包含了Connection: close首部,不然HTTP/1.1连接就仍维持在打开状态。但是,客户端和服务器仍然可以随时关闭空闲的连接。不发送 connection: close并不意味着服务器承诺永远将连接保持在打开状态。
管道化连接
HTTP/1.1允许在持久连接上可选地使用请求管道。这是在keep-alive连接上的进一步性能优化。在响应到达之前,可以将多条请求放入队列。当第一条请求通过网络流向地球另一端的服务器时,第二条和第三条请求也可以开始发送了。在高时延网络条件下,这样做可以降低网络的环回时间,提高性能。
关闭连接
四.代理
Web代理(proxy)服务器是网络的中间实体,位于客户端和服务器之间,扮演”中间人的角色,在各端点之间来回传送HTTP报文”
私有和共享代理
代理服务器可以是某个客户端专用的,也可以是很多客户端共享的.单个客户端专用的代理被称为私有代理.众多客户端共享的代理被称为公共代理.
代理和网关的对比
代理连接的是两个或多个是同相同协议的应用程序,而网关连接的是两个或多个使用不同协议的端点.网关扮演的是”协议转换器”的角色,即使客户端和服务器使用的是不同的协议,客户端也可以通过它完成与服务器之间的事务处理.如下图
实际上,代理和网关之间的区别很模糊.由于浏览器和服务器实现的是不同版本的HTTTP,代理也经常要做一些协议转换工作.而商业化的代理服务器也会实现网关的功能来支持SSL安全协议,SICKS防火墙,FTP访问等.
为什么使用代理
代理服务器可以实现各种时髦且有用的功能。它们可以改善安全性,提高性能,节省费用。代理服务器可以看到并接触到所有流过的HTTP流量,所以代理可以监视流量并对其进行修改,以实现很多有用的增值Web服务。
- 儿童过滤器
代理URI与服务器URI的不同
客户端向服务器和代理发送请求时,HTTP报文中的URI有所不同,除了这一点,服务器报文和代理报文语法是一样的.
客户端向web服务器发送请求时,请求行中只包含部分URI(没有方案,主机或者端口),如下
但是向代理发送请求时,请求行中则包含完整的URI,如下
URI的客户端自动扩展和主机名解析
没有代理时URI的解析
在没有代理的情况下,浏览器进行主机名自动扩展,如下图
有显示代理时URI的解析
使用显示代理时,用户的URI会被直接发送给代理,所以浏览器就不再执行所有的便捷的扩展功能了.
Via首部字段
Via首部字段用于记录报文的转发,诊断报文循环,标识请求/响应链上所有发送者的协议能力.
代理也可以使用Via首部来检测网络中的路由循环.代理应该在发送一条请求之前,在ia首部插入一个与其自身有关的独特字符串,并在输入的请求中查找这个字符串,以检测网络中是否存在路由循环.
代理也可以为使用非HTTP协议的服务器提供网关的功能.Via首部记录了这些协议转换.这时Via字段中协议的版本号之前必须加上协议的类型(如果是HTTP协议则可加可不加)如下图
可以使用Max-Forwards首部来限制请求报文经过代理转发的跳数.
代理认证
五.缓存
缓存优点
- 减少了冗余的数据传输,节省了网络费用
- 缓解了网络瓶颈的问题,不需要更多的带宽就能更快的加载页面
- 降低了对原始服务器的要求,服务器可以更快的响应,避免了过载的出现
- 降低了距离时延,因为从较远的地方加载页面会更慢一些
命中和未命中
缓存命中:可以用已有的副本为某些到达缓存的请求提供服务.
缓存未命中:一些到达缓存的请求可能会由于没有副本可用,而被转发给原始服务器,
再验证:原始服务器的内容可能会发生变化,缓存要不时对其进行检测,看看它们保存的副本是否仍是服务器上的最新版本.这些新鲜度检测称为HTTP再验证.
验证再命中:缓存对缓存的副本进行再验证时,会向原始服务器发送一个小的在验证请求,如果内容没有变化,服务器会以一个小的304 Not Modified进行响应,缓存知道副本仍然有效.,就会再次将副本标识为暂时新鲜的,并将副本提供给客户端,这被称为再验证命中,或者缓慢命中.
再验证的工具最常用的就是If-Modified-Since首部,将这个首部添加到get请求中,就可以告诉服务器,只有在缓存了对象的副本之后,又对其进行了修改的情况下,才发送此对象.
区分命中和未命中的情况
HTTP没有为用户提供一种手段来区分响应是缓存命中的还是访问原始服务器得到的,在这两种情况下,响应码都是200OK.
客户端可以使用Date首部,将响应中Date首部的值与当前时间进行比较,如果响应中的日期比较早,客户端就可以认为这是一条缓存的响应.
也可以通过Age首部来检测缓存的响应,通过这个首部可以分辨出这条响应的使用期.
缓存处理过程
新鲜度检测
HTTP有一些简单的机制可以在不要求服务器记住哪些缓存拥有其文档副本的情况下,保持已缓存数据与服务器数据之间充分一致.HTTP将这些简单的机制称为文档过期和服务器再验证.
文档过期(强缓存)
通过特殊的HTTP Cache-Control首部和Expires首部,HTTP让原始服务器向每个文档附加了一个’过期日期’(如下图).
服务器再验证
已缓存的文档过期并不意味着它和服务器上的文档有实际的区别,这只是意味着到了要进行核对的时间了,这种情况被称为’服务器再验证’,说明缓存需要询问原始服务器文档是否发生了变化.
条件方法再验证(协商缓存)
If-Modified-Since日期再验证
If-Modified-Since首部(一般称为IMS)可以与Last-Modified服务器响应首部配合工作.如下图为一个工作流程示例.
If-None-Match实体标签再验证
如果服务器回送了实体标签ETag,HTTP/1.1客户端就必须使用实体标签验证器.如果HTTP/1.1缓存或者服务器收到的请求既带有If-Modified-Since又带有实体标签条件首部,那么只有这两个条件都满足时,才能返回304Not Modified响应.
控制缓存的能力
服务器可以通过HTTP定义的几种方式来指定在文档过期之前可以将其缓存多长时间,按照优先级递减的顺序,服务区可以:
- 附加一个Cache-Control : no-store首部到响应中去;
- 附加一个cache-Control : no-cache首部到响应中去,
- 附加一个cache-Control : must-revalidate首部到响应中去;
- 附加一个cache-Control : max-age首部到响应中去;
- 附加一个 Expires日期首部到响应中去;
- 不附加过期信息,让缓存确定自己的过期日期。
no-Store和no-Cache响应首部
no-store首部和no-cache首部可以防止缓存提供未经证实的已缓存对象:
标识为no-store的响应会禁止缓存对响应进行复制。缓存通常会像非缓存代理服务器一样,向客户端转发一条no-store响应,然后删除对象。
标识为no-cache的响应实际上是可以存储在本地缓存区中的。只是在与原始服务器进行新鲜度再验证之前,缓存不能将其提供给客户端使用。这个首部使用do-not-serve-from-cache-without-revalidation这个名字会更恰当一些。(即协商缓存)
客户端识别与cookie机制
HTTP并不是天生就具有丰富的识别特性的,下面讨论几种用户识别机制.
HTTP首部
下图中给出了七种最常见的用来承载用户相关信息的HTTP请求首部
From首部包含了用户的E-mail地址,但是由于担心那些不讲武德的服务器会搜集这些E-mail地址用于辣鸡邮件的散发,所以很少有浏览器会发送From首部.
User-Agent首部可以将用户所用浏览器相关信息告知服务器,包括程序的名称和版本,通常还包括操作系统的相关信息.要实现定制内容与特定的浏览器及其属性间的良好交互操作时,这个首部很有用.
Referer首部提供了用户来源页面的URL.Referer首部自身并不能完全识别用户,但它可以说明用户之前访问过哪个页面,从而直到用户的行为和兴趣.
这三种首部都不足以实现可靠的识别
客户端IP地址
通常在HTTP首部并不提供客户端的IP地址,但web服务器可以找到承载HTTP请求的TCP连接另一端的IP地址.
但是客户端IP地址来识别用户存在着很多缺点,限制了将其作为用户识别技术的效能.
- 客户端IP地址描述的是机器,不是用户,如果几个用户共享一台计算机就无法区分.
胖URL
有些Web站点会为每个用户生成特定版本的URL来追踪用户的身份。通常,会对真正的 URL进行扩展,在 URL路径开始或结束的地方添加一些状态信息。用户浏览站点时,Web服务器会动态生成一些超链,继续维护URL中的状态信息。改动后包含了用户状态信息的URL被称为胖URL (fat URL)。
cookie
cookie的类型
会话cookie和持久cookie.会话cookie是一种临时cookie,它记录了用户访问站点时的设置和偏好,用户退出浏览器时,会话cookie就被删除了.持久cookie的生存时间更长一些,它们存储在硬盘上,浏览器退出,计算机重启时他们仍然存在,通常会用持久cookie维护某个用户会周期性访问的站点的配置文件或登录名.
会话cookie和持久cookie的唯一区别就是过期时间.如果设置了Discard参数,或者没有设置Expires或Max-Age参数来说明扩展的过期时间,这个cookie就是一个会话cookie.
cookie罐:客户端的状态
cookie的基本思想就是让浏览器积累一组服务器特有的信息,每次访问服务器时都将这些信息提供给他.
不同站点使用不同的cookie
cookie的域属性
产生cookie的服务器可以向Set-Cookie响应首部添加一个Domain属性来控制哪些站点可以看到哪个cookie,比如下面的示例就是在告诉浏览器将cookie user=”mary17”发送给域”.air……..com”中的所有站点.
1 | set-cookie: user= "mary17" ; domain="airtravelbargains.com" |
如果用户访问的是www.airtravelbargains.com、specials.airtravelbargains.com或任意以.airtravelbargains.com结尾的站点,Cookie: user=”mary17”首部都会被发布出去
cookie的路径属性
cookie规范甚至允许用户将cookie与部分Web站点关联起来。可以通过Path属性来实现这一功能,在这个属性列出的URL路径前缀下所有cookie都是有效的。例如,某个 Web服务器可能是由两个组织共享的,每个组织都有独立的cookie。站点www.airtravelbargains.com可能会将部分Web站点用于汽车租赁——比如,http://www.airtravelbargains.com/autosl——用一个独立的cookie来记录用户喜欢的汽车尺寸。可能会生成一个如下所示的特殊汽车租赁cookie:
1 | set-cookie: pref=compact; domain="airtravelbargains.com" ; path=/autos/ |
只有用户访问/auto/**才会返回Cookie:pref=compact这个首部
cookies1版本相对于cookies0版本改动
- 为每个cookie关联上解释性文本,对其目的进行解释。
- 允许在浏览器退出时,不考虑过期时间,将cookie强制销毁。用相对秒数,而不是绝对日期来表示cookie 的 Max-Age.
- 通过URL端口号,而不仅仅是域和路径来控制cookie的能力。
- 通过cookie首部回送域、端口和路径过滤器(如果有的话)。
- 为实现互操作性使用的版本号。
- 在cookie首部从名字中区分出附加关键字的$前缀。
安全HTTP
使用HTTPS时,所有的HTTP请求和响应数据在发送到网络之前,都要进行加密。HTTPS在 HTTP下面提供了一个传输级的密码安全层如图.
数字加密
给定一段明文报文P、一个编码函数E和一个数字编码密钥e,就可以生成一段经过编码的密文C。通过解码函数D和解码密钥d,可以将密文C解码为原始的明文P。当然,编/解码函数都是互为反函数的,对P的编码进行解码就会回到原始报文P上去。如图所示.
对称密钥加密技术
对称密钥(symmetric-key)加密技术,这是因为它们在编码时使用的密钥值和解码时一样(e=d)。我们就将其统称为密钥k。
对称密钥加密技术得缺点之一就是发送者和接收者在互相对话之前,一定要有一个共享的保密密钥.
比如 Alice (A)、Bob (B)和 Chris (C)都想与Joe的五金商店(J)对话。A、B和C都要建立自己与J之间的保密密钥。A可能需要密钥K^,B可能需要密钥KB,C可能需要密钥K“。每对通信实体都需要自己的私有密钥。如果有N个节点,每个节点都要和其他所有N-1个节点进行安全对话,总共大概会有N个保密密钥:这将是一个管理噩梦。
公开密钥加密技术
公开密钥加密技术没有为每对主机使用单独的加密/解密密钥,而是使用了两个非对称密钥:一个用来对主机报文编码,另一个用来对主机报文解码。编码密钥是众所周知的(这也是公开密钥加密这个名字的由来),但只有主机才知道私有的解密密钥。这样,每个人都能找到某个特定主机的公开密钥,密钥的建立变得更加简单。但解码密钥是保密的,因此只有接收端才能对发送给它的报文进行解码。
混合加密
任何人只要知道了其公开密钥,就可以向一台公共服务器发送安全报文,所以非对称的公开密钥加密系统是很好用的。两个节点无须为了进行安全的通信而先交换私有密钥。
但公开密钥加密算法的计算可能会很慢。实际上它混合使用了对称和非对称策略。比如,比较常见的做法是在两节点间通过便捷的公开密钥加密技术建立起安全通信,然后再用那条安全的通道产生并发送临时的随机对称密钥,通过更快的对称加密技术对其余的数据进行加密。
数字签名
除了加/解密报文之外,还可以用加密系统对报文进行签名(sign),以说明是谁编写的报文,同时证明报文未被篡改过。这种技术被称为数字签名(digital signing)
数字签名通常是用非对称公开密钥技术产生的。因为只有所有者才知道其私有密钥,所以可以将作者的私有密钥当作一种“指纹”使用。下图是一个例子,说明了节点A是如何向节点B发送一条报文并对其进行签名得.
数字证书
数字证书中包含了由某个受信任组织担保得用户或公司的相关信息.
HTTPS
概述
HTTPS在将HTTP报文发送给TCP之前,先将其发送给了一个安全层,对齐进行加密
请求一个客户端(比如Web浏览器)对某Web资源执行某事务时,它会去检查URL的方案。
- 如果URL的方案为http,客户端就会打开一条到服务器端口80(默认情况下)的连接,并向其发送老的HTTP命令(参见图14-14a)。
- 如果URL的方案为https,客户端就会打开一条到服务器端口443(默认情况下)的连接,然后与服务器“SSL握手”,以二进制格式与服务器交换一些SSL安全参数,附上加密的HTTP命令(参见图14-14b)。
SSL握手
在发送已加密的 HTTP报文之前,客户端和服务器要进行一次SSL 握手,在这个握手过程中,它们要完成以下工作,过程如图
- 交换协议版本号;
- 选择一个两端都了解的密码
- 对两端的身份进行认证;
- 生成临时的会话密钥,以便加密信道。
为什么不一直使用HTTPS
其中一个原因是,因为与纯文本通信相比,加密通信会消耗更多的 CPU 及内存资源。如果每次通信都加密,会消耗相当多的资源,平 摊到一台计算机上时,能够处理的请求数量必定也会随之减少。因此,如果是非敏感信息则使用 HTTP 通信,只有在包含个人信息 等敏感数据时,才利用 HTTPS 加密通信。
除此之外,想要节约购买证书的开销也是原因之一。