详解HTTP中的摘要认证机制(转)
Basic认证方式是存在很多缺陷的,具体表现如下:
1, Basic认证会通过网络发送用户名和密码,并且是以base64的方式对用户名和密码进行简单的编码后发送的,而base64编码本身非常容易被解码,所以经过base64编码的密码实际上是明文发送的。
2, 即使密码是经过加密传输的,当第三方用户仍然可以捕获被修改过的用户名和密码,并将修改过的用户名和密码反复多次的重放给原始服务器,以获得对服务器的访问权,Basic认证没有什么措施可以用来防止这些重放攻击。
3, 一些不良习惯会使得Basic认证更加危险,那就是用户由于受不了大量密码保护的服务,会在这些不同的服务间使用相同的用户名和密码。
4, Basic认证没有提供任何针对代理和作为中间人的中间节点的防护措施,它们没有修改认证首部,但却能够修改报文的其余部分,这样就严重的改变了事务的本质。即Basic认证没法支持对内容或者报文本身的保护。
5, Basic不支持对称认证,即客户端无法认证服务器的合法性,因此客户端很容易被钓鱼到一个非法的服务器从而输入了用户名和密码。
综上,Basic 认证存在很多的不足,使得一般只能用在一些非常简单场景而不能很好的支持真正的产品级别的运用。
下面要介绍的另外一种认证,摘要认证则针对Basic认证存在的诸多问题而进行的改良方案。
摘要认证时另外一种HTTP认证协议,它试图修复Basci认证的严重缺陷,即进行如下改进:
1, 通过传递用户名,密码等计算出来的摘要来解决明文方式在网络上发送密码的问题。
2, 通过服务产生随机数nonce的方式可以防止恶意用户捕获并重放认证的握手过程。
3, 通过客户端产生随机数cnonce的方式,支持客户端对服务器的认证。
4, 通过对内容也加入摘要计算的方式,可以有选择的防止对报文内容的篡改。
但是,摘要认证并不是罪安全的协议,也无法满足安全HTTP事务的很多需求,对这些需求来说,可能使用HTTPS方式更为合适。
一,用摘要保护密码
摘要认证的一个改进之处是用摘要代替密码的传输,遵循的基本原则是“绝对不通过网络发送明文密码”,而是发送一个密码的摘要信息,并且这摘要信息是不可逆的,即无法通 过摘要信息反推出密码信息。而服务器本身是存储这个密码的(实际上,服务器只需知道密码的摘要即可),而客户端和服务器本身都知道这个密码。这样的话,服务器可以读取客户端的摘要和本身知道的密码进行同样计算得出的摘要进行比较,若匹配,则验证通过。
摘要是对信息主体的浓缩,摘要是一种单向函数,主要用于将无限的输入值转为有限的浓缩输出值,如MD5,则是将任意长度的字节系列转换为一个128位的摘要。MD5输出的128位的摘要通常会写出32个十六进制的字符,每个字符表示4个bit。
二,用随机数防止重放攻击
使用单向摘要就无需以明文形式发送密码了,可以只发送密码的摘要,并且可以确信,没有哪个恶意用户能轻易的从摘要中解码出原始密码。
但是,摘要被截获也可能跟密码一起好用,为了防止重放攻击的发送,服务器可以向客户端发送一个称为随机数nonce的特殊令牌,这个数会经常发生变化(可能是每毫秒,或者每次认证都发生变化,具体由服务器控制),客户端在计算摘要之前要先将这个随机数附加到密码上去。这样,在密码中加入随机数就会使得摘要随着随机数的每次变化而变化,记录下的密码摘要只对特定的随机数有效,而没有密码的话,攻击者就无法计算出正确的摘要,这样就可以防止重放攻击的发生。
摘要认证要求使用随机数,随机数是在WWW-Authenticate服务器质询响应中从服务器传输给客户端的。
三,摘要认证的握手过程
1, 第一次客户端请求的时候,服务器产生一个随机数nonce,服务器将这个随机数放在WWW-Authenticate响应头,与服务器支持的认证算法列表,认证的域realm一起发送给客户端,如下例子:
HTTP /1.1 401 Unauthorized
WWW-Authenticate:Digest
realm= ”test realm”
qop=auth,auth-int”
nonce=”66C4EF58DA7CB956BD04233FBB64E0A4”
2, 客户端发现是401响应,表示需要进行认证,则弹出让用户输入用户名和密码的认证窗口,客户端选择一个算法,计算出密码和其他数据的摘要,将摘要放到Authorization的请求头中发送给服务器,如果客户端要对服务器也进行认证,这个时候,可以发送客户端随机数cnonce。如下例子:
GET/cgi-bin/checkout?a=b HTTP/1.1
Authorization: Digest
username=”tenfyguo”
realm=”test realm”
nonce=” 66C4EF58DA7CB956BD04233FBB64E0A4” //服务器端的随机数一起带回
uri=”/cgi-bin/checkout?a=b” //必须跟请求行一致
qop=”auth” //保护质量参数
nc=0000001
cnonce=”xxxxx234132543strwerr65sgdrftdfytryts” //客户端随机数,用于对称校验
response=” ABC4EF58DA7CB956BD04345FBB64E0A4”//最终摘要
3, 服务接受摘要,选择算法以及掌握的数据,重新计算新的摘要跟客户端传输的摘要进行比较,验证是否匹配,若客户端反过来用客户端随机数对服务器进行质询,就会创建客户端摘要,服务可以预先将下一个随机数计算出来,提前传递给客户端,通过Authentication-Info发送下一个随机数。如下例子:
HTTP/1.1 200 OK
Authorization-Info:nextnonce=” 88C4EF58DA7CB956BD04233FBB64E0A4”
qop=”auth”
rspauth=”23543534DfasetwerwgDTerGDTERERRE”
cnonce=” xxxxx234132543strwerr65sgdrftdfytryts”
四,摘要的计算
在说明如何计算摘要之前,先说明参加摘要计算的信息块。信息块主要有两种:
1,表示与安全相关的数据的A1。
A1中的数据时密码和受保护信息的产物,它包括用户名,密码,保护域和随机数等内容,A1只涉及安全信息,与底层报文自身无关。
若算法是:MD5
则A1=<user>:<realm>:<password>
若算法是:MD5-sess
则A1=MD5(<user>:<realm>:<password>):<nonce>:<cnonce>
2,表示与报文相关的数据的A2.
A2表示是与报文自身相关的信息,比如URL,请求反复和报文实体的主体部分,A2加入摘要计算主要目的是有助于防止反复,资源或者报文被篡改。
若qop未定义或者auth:
A2=<request-method>:<uri-directive-value>
若qop为auth:-int
A2=<request-method>:<uri-directive-value>:MD5(<request-entity-body>)
下面定义摘要的计算规则:
若qop没有定义:
摘要response=MD5(MD5(A1):<nonce>:MD5(A2))
若qop为auth:
摘要response=MD5(MD5(A1):<nonce>:<nc>:<cnonce>:<qop>:MD5(A2))
若qop为auth-int:
摘要response= MD5(MD5(A1):<nonce>:<nc>:<cnonce>:<qop>:MD5(A2))
五,随机数的生成
RFC2617建议采用这个假想的随机数公式:
nonce = BASE64(time-stamp MD5(time-stamp “:” ETag “:” private-key))
其中:
time-stamp是服务器产生的时间戳或者其他不会重复的序列号,ETag是与所请求实体有关的HTTP ETag首部的值,priviate-key是只有服务器知道的数据。
这样,服务器就可以收到客户端的认证首部之后重新计算散列部分,如果结果与那个首部的随机数不符,或者是时间戳的值不够新,就可以拒绝请求,服务器可以通过这种方式来限制随机数的有效持续时间。
包括了ETag可以防止对已经更新资源版本的重放请求。注意:在随机数中包含客户端IP,服务器好像就可以限制原来获取此随机数的客户端重用这个随机数了,但这会破坏代理集群的工作,使用代理集群时候,来自单个用户的多条请求通常会经过不同的代理进行传输,而且IP地址欺骗实现起来也不复杂。
转自:http://blog.csdn.net/tenfyguo/article/details/8661517
详解HTTP中的摘要认证机制(转)的更多相关文章
- HTTP中的摘要认证机制
引子: 指定和服务器端交互的HTTP方法,URL地址,即其他请求信息: Method:表示http请求方法,一般使用"GET","POST". url:表示请求 ...
- 详解Redis中两种持久化机制RDB和AOF(面试常问,工作常用)
redis是一个内存数据库,数据保存在内存中,但是我们都知道内存的数据变化是很快的,也容易发生丢失.幸好Redis还为我们提供了持久化的机制,分别是RDB(Redis DataBase)和AOF(Ap ...
- 详解Redis中两种持久化机制RDB和AOF
redis是一个内存数据库,数据保存在内存中,但是我们都知道内存的数据变化是很快的,也容易发生丢失.幸好Redis还为我们提供了持久化的机制,分别是RDB(Redis DataBase)和AOF(Ap ...
- react第五单元(事件系统-原生事件-react中的合成事件-详解事件的冒泡和捕获机制)
第五单元(事件系统-原生事件-react中的合成事件-详解事件的冒泡和捕获机制) 课程目标 深入理解和掌握事件的冒泡及捕获机制 理解react中的合成事件的本质 在react组件中合理的使用原生事件 ...
- 【转】详解C#中的反射
原帖链接点这里:详解C#中的反射 反射(Reflection) 2008年01月02日 星期三 11:21 两个现实中的例子: 1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内 ...
- 详解Objective-C中委托和协议
Objective-C委托和协议本没有任何关系,协议如前所述,就是起到C++中纯虚类的作用,对于“委托”则和协议没有关系,只是我们经常利用协议还实现委托的机制,其实不用协议也完全可以实现委托. AD: ...
- 图文详解 Android Binder跨进程通信机制 原理
图文详解 Android Binder跨进程通信机制 原理 目录 目录 1. Binder到底是什么? 中文即 粘合剂,意思为粘合了两个不同的进程 网上有很多对Binder的定义,但都说不清楚:Bin ...
- Java集合详解3:Iterator,fail-fast机制与比较器
Java集合详解3:Iterator,fail-fast机制与比较器 今天我们来探索一下LIterator,fail-fast机制与比较器的源码. 具体代码在我的GitHub中可以找到 https:/ ...
- 使用IDEA详解Spring中依赖注入的类型(上)
使用IDEA详解Spring中依赖注入的类型(上) 在Spring中实现IoC容器的方法是依赖注入,依赖注入的作用是在使用Spring框架创建对象时动态地将其所依赖的对象(例如属性值)注入Bean组件 ...
随机推荐
- 关于Javascript函数的几点笔记
函数本质上是一个有名字的程序块,程序块使得多条语句可以一起执行. 变量类型: 1.复杂类型:Object.Array等. 2.原始类型:String.Integer等. 函数参数: 1.复杂类型:传递 ...
- 利用Java自带的MD5加密java.security.MessageDigest;
MD5加密算法,即"Message-Digest Algorithm 5(信息-摘要算法)",它由MD2.MD3.MD4发展而来的一种单向函数算法(也就是HASH算法),它是国际著 ...
- add-two-numbers-ii
注意:有一种好的方法,是将链表倒转,然后依次相加. 但是,按照题目要求,用了不改变原链表的方法. 就是将两个链表增加到相同长度,然后递归相加,子函数返回后处理进位. https://leetcode. ...
- uva1639 Candy
组合数,对数. 这道题要用到20w的组合数,如果直接相乘的话,会丢失很多精度,所以用去对数的方式实现. 注意指数,因为取完一次后,还要再取一次才能发现取完,所以是(n+1)次方. double 会爆掉 ...
- HTTPS通信机制
概述 使用HTTP协议进行通信时,由于传输的是明文所以很容易遭到窃听,就算是加密过的信息也容易在传输中遭受到篡改,因此需要在HTTP协议基础上添加加密处理,认证处理等,有了这些处理机制的HTTP成为H ...
- (转)TCP协议那些事
(上) TCP是一个巨复杂的协议,因为他要解决很多问题,而这些问题又带出了很多子问题和阴暗面.所以学习TCP本身是个比较痛苦的过程,但对于学习的过程却能让人有很多收获.关于TCP这个协议的细节,我还是 ...
- Xcode中使用svn时,报证书验证错误Error validating server certificate for
转:http://blog.csdn.net/yhawaii/article/details/7511141 今天使用Xcode自带的svn客户端时,总是连接不上服务器,报如下错误: Error va ...
- 顶 企业站常用css横向导航菜单
<!DOCTYPE html PUBliC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/T ...
- centos使用网易163yum源
CentOS系统自带的更新源的速度实在是慢,为了让CentOS6使用速度更快的YUM更新源,可以选择163(网易)的更新源. 1.下载repo文件 wget http://mirrors.163.co ...
- 【c++内存分布系列】单独一个类
首先要明确类型本身是没有具体地址的,它是为了给编译器生成相应对象提供依据.只有编译器生成的对象才有明确的地址. 一.空类 形如下面的类A,类里没有任何成员变量,类的sizeof值为1. #includ ...