HTTP认证

HTTP基本认证(basic authentication)就是简单的质询/回应 (challenge/response)

试图访问一个受基本认证保护的资源时,没有提供正确的证书,那么会收到服务器对你身份的质询,然后必须重新发出请求。

例如 客户端 发送一个没有给出证书的请求

GET /xxxx.html HTTP/1.1

Host: www.example.com

服务器的响应会如下:

401 Unauthorized

WWW-Authrnticate: Basic realm='my private Data'

(这里指出了应该采用的认证方案 基本认证,还指定了realm,通常用于标识网站上的一组资源,可以是任意名称。认证类型表明采用哪种认证方案 如‘Basic’,而realm 表明对什么‘my private Date’ 进行认证)

客户端需要以用户名和密码来回应基本认证的质询。用户名和密码信息也许已经保存在属于该realm的缓冲了,假如没有的话客户端将提示最终用户输入。客户端获得用户名和密码后,会把这两则信息转换为一个采用base64编码的字符串。许多编程语言都提供了用于进行base64位编码的标准库。这个看似由随机字符组成的字符串就是Authorization报头的值

基本认证实际上是用明文来传递用户名密码的,解决办法就是采用HTTPS

这儿的证书:可以是一个用户名/密码。也可以是一个API key,或者一个认证令牌

摘要认证

摘要认证是另一种防止证书被窃听的办法,它能确保在非加密的HTTP上传输证书的安全,摘要认证的基本模式跟基本认证一样,即客户端发出请求后,得到服务器返回的质询。

如:

401 Unauthorized

WWW-Authenticate:Digest realm="My private data",qop="auth",nonce="0cc175sjdhs7866s767sa8sdds77",opaque="98e887ff8sdc00889v"

这里WWW-Authenticate报头指出认证类型是摘要认证(“Digest”)。另外还包含了3则其他信息。nonce:随机字符串,每个请求的nonce值都不相同。

客户端的任务是把这则信息转换为一个加密的字符串,以证明客户端知道正确的密码。但该字符串并不包含实际的密码。

客户端首先生成一个客户端nonce和一个序号。

然后,客户端根据以下信息构造一个“摘要”字符串:

请求里的HTTP方法

URI路径

质询响应里的四则信息

以及用户名、密码、客户端nonce、序号。

摘要认证构造摘要字符串的过程,要比基本认证构造base64字符串复杂的多

为HTTP摘要认证构造摘要字符串的例子(ruby):

 1 #原请求里的信息
 2 
 3 METHOD="GET"
 4 
 5 PATH="/resource.html"
 6 
 7 #质询响应里的信息
 8 
 9 REALM=“My private data”
10 
11 NONCE="0cc175sjdhs7866s767sa8sdds77"
12 
13 OPAQUE="98e887ff8sdc00889v"
14 
15 QOP="auth"
16 
17 #客户端已知或计算出的信息
18 
19 NC="00000001" (请求计数器)
20 
21 CNONCE='4a9a08df00f0e00b87676' (客户码随机数)
22 
23 USER='Alibaba'
24 
25 PASSWORD='opens sesame'
26 
27 #计算最终的摘要的三个步骤
28 
29 ha1=MD5::hexdigest("#{USER}:#{REALM}:#{PASSWORD}")
30 
31 ha2=MD5::hexdigest("#{METHOD}:#{PATH}")
32 
33 ha3=MD5::hexdigest("#{ha1}:#{NONCE}:#{NC}:#{CNONCE}:#{QOP}:#{ha2}")
34 
35 puts ha3

 算出摘要字符串之后,客户端就可以重新发送请求,并把所有常量(除了密码)及摘要字符串传回给服务器了:

虽然摘要认证比较复杂,但其流程跟基本认证是一样的:请求、质询、回应。摘要认证更基本认证的关键不同在于:即便是服务器,页无法根据摘要获知你确切的密码。当用户为某个realm首次设置密码时,服务器需要为user:realm:password计算哈希值(上面的ha1),然后记录下来。当服务器需要进行身份验证时,可以直接利用这个值计算出最终的ha3,而不必再需要用户名和密码。

另一个区别在于,客户端的每个请求,实际上对应着两次请求,第一次请求的目的是获得质询响应。这次请求不包含认证信息,并且该请求得到的响应总具有响应代码401,但该响应的WWW-Authenticate报头里包含一个唯一的nonce,客户端需要用这个nonce值来构造正确的Authorization报头。接着,客户端发出第二次请求,这次请求里包含Authorization报头,应该会成功。

摘要认证中把qop=auth-int改成qop=auth表明:在计算ha2时,除了要包括HTTP方法和URI路径以外,还要包括请求实体主体--这可以防止PUT和POST请求的表示被某个中间人篡改

原文地址:https://www.cnblogs.com/aveenzhou/p/3369750.html