小话HTTP Authentication

news/2024/12/29 16:11:29/

什么是Authentication?

首先解释两个长的很像、容易混淆的单词,Authentication(鉴定、认证)Authorization(授权)

Authentication就是要证明你是谁。举个例子,你告诉别人你的名字叫Alice,怎么样让别人确信你就是Alice,这就是Authentication。

Authorization则是当别人已经相信是你以后,你是不是被允不允许做做某件事儿。比如,当你已经证明了你就是Alice了,你可以查你自己的信用卡刷卡记录,但不能查Bob的刷卡记录,这就是Authorization(当然,如果Alice是Bob的老婆这种情况除外)。


这篇博客就主要看看HTTP Authentication到底是怎么回事。然后两种常见的Authentication机制:HTTP Basic和Digest。


HTTP Basic

顾名思义,HTTP Basic指的就是最简单的Authentication协议。简单到什么份儿上呢?直接方式告诉服务器你的用户名(username)和密码(password)。这里假设我们的用户名是Alice,密码是123456。


我们使用curl访问服务器

   curl -u Alice:123456 http://kiwiserver.com/secret -v


request头部:

 GET /secret HTTP/1.1
 Authorization: Basic QWxpY2U6MTIzNDU2
 ...

我们这里看到发送的request头部中含有Authentication这个字段,其值为Basic QWxpY2U6MTIzNDU2。Basic表示的使用的是HTTP Basic Authentication。而QWxpY2U6MTIzNDU2,则是由“Alice:123456”进行Base64编码以后得到的结果。


response头部: 

 HTTP/1.1 200 OK
 ...

因为我们输入的是正确的用户名密码,所以服务器会返回200,表示验证成功。如果我们用错误的用户的密码来发送请求,则会得到类似如下含有401错误的response头部:

 HTTP/1.1 401 Bad credentials
 WWW-Authenticate: Basic realm="Spring Security Application"
 ...


乍看起来好像HTTP Basic还挺不错的,QWxpY2U6MTIzNDU2已经让人很难看出来用户名密码是什么了。但是,我们需要知道Base64编码是可逆的。也就是我们可以通过decode Base64的编码还原用户名和密码。

在命令行输入如下命令:

   echo QWxpY2U6MTIzNDU2 | base64 -D

得到:

   Alice:123456

轻松解密。试想,如果一个人通过一定的方法截获了Alice向服务器发送的请求,那不是很容易就能够得到她的用户名和密码了吗?所以,为了保证用户的安全,我们不会直接通过HTTP的方式使用Basic Authentication,而是会使用HTTPS,这样更安全一些。



Replay Attack

通过前面介绍,我们知道了通过可逆的Base64的编码方式不是太靠谱,那我们在发送密码之前,将密码用不可逆的方式进行编码不就完了吗?

比如,前面Alice的密码是123456,进行MD5编码

   md5 -s 123456

以后得到的就是

e10adc3949ba59abbe56e057f20f883e

这样不就是不可逆的了?恩,即使有一个叫Craig的家伙截获了我向服务器发送的用户名密码,他也不知道我的密码到底是什么了。

的确,Craig拿到e10adc3949ba59abbe56e057f20f883e这个被md5 hash过的密码也不知道Alice的密码是什么。但是,如果Craig直接拿着这个字符串放在HTTP头部,再发送给服务器不就OK了?Craig这样就根本不用解密这个密码也能装成“Alice”向服务器通信。这就叫做Replay Attack。



HTTP Digest

为了避免被坏人使用Replay Attack,一个简单的想法就是,让我们每次向服务器发送的认证信息都“必须”是不一样的,这样Craig即使拿到了这个认证信息也没有办法进行replay attack了。那如何让Alice每次向服务器发送的认证信息都是不一样的,同时能够让服务器知道这就是Alice呢?

这就引出了Digest Authentication了。当Alice初次访问服务器时,并不携带密码。此时服务器会告知Alice一个随机生成的字符串(nonce)。然后Alice再将这个字符串与她的密码123456结合在一起进行MD5编码,将编码以后的结果发送给服务器作为验证信息。

因为nonce是“每次”(并不一定是每次)随机生成的,所以Alice在不同的时间访问服务器,其编码使用的nonce值应该是不同的,如果携带的是相同的nonce编码后的结果,服务器就认为其不合法,将拒绝其访问。这样,即使Craig能够截获Alice向服务器发送的请求,也没有办法使用replay attack冒充成Alice了。


我们还是可以使用curl来查看这一过程:

   curl -u Alice:123456 http://kiwiserver.com/secret -v --digest


curl和服务器通信过程

curl -------- request1:GET ------->> Server

curl <<------ response1:nonce ------- Server

curl ---- request2:Digest Auth ----> Server

curl <<------- response2:OK --------  Server


request1头部:
 GET /secret HTTP/1.1
 ...
请求1中没有包含任何用户名和密码信息

response1头部:
 HTTP/1.1 401
Full authentication is required to access this resource
 WWW-Authenticate: Digest realm="Contacts Realm via Digest Authentication", qop="auth",nonce="MTQwMTk3OTkwMDkxMzo3MjdjNDM2NTYzMTU2NTA2NWEzOWU2NzBlNzhmMjkwOA=="
 ...

当服务器接收到request1以后,认为request1没有任何的Authentication信息,所以返回401,并且告诉curl nonce的值是MTQwMTk3OTkwMDkxMzo3MjdjNDM2NTYzMTU2NTA2NWEzOWU2NzBlNzhmMjkwOA

request2头部:

 GET /secret HTTP/1.1
 Authorization: Digest username="Alice", realm="Contacts Realm via Digest Authentication",nonce="MTQwMTk3OTkwMDkxMzo3MjdjNDM2NTYzMTU2NTA2NWEzOWU2NzBlNzhmMjkwOA==", uri="/secret", cnonce="MTQwMTk3", nc=00000001, qop="auth",response="fd5798940c32e51c128ecf88472151af"
 ...

curl接收到服务器的nonce值以后,就可以把如密码等信息和nonce值放在一起然后进行MD5编码,得到一个response值,如前面红色标出所示,这样服务器就可以通过这个值验证Alice的密码是否正确。


response2头部:

 HTTP/1.1 200 OK
 ...


当我们完成Authentication以后,如果我们再次使用刚才的nonce值:

   curl -X GET http://kiwisecrect.com/secret -H 'Authorization: Digest username="Alice", realm="Contacts Realm via Digest Authentication", nonce="MTQwMTk3OTkwMDkxMzo3MjdjNDM2NTYzMTU2NTA2NWEzOWU2NzBlNzhmMjkwOA==", uri="/secret", cnonce="MTQwMTk3", nc=00000001, qop="auth", response="fd5798940c32e51c128ecf88472151af"' -v

收到错误信息:

 HTTP/1.1 401 Incorrect response
 WWW-Authenticate: Digest realm="Contacts Realm via Digest Authentication", qop="auth", nonce="MTQwMTk4Mjg4MjQ5NjpjZmNiNzI2ZmFlNzA4Nzg3ZDUxNjk2YTEyMTU3OTc0Yg=="


Digest Authentication比Basic安全,但是并不是真正的什么都不怕了,Digest Authentication这种容易方式容易收到Man in the Middle式攻击。(未完待续)


http://www.ppmy.cn/news/171784.html

相关文章

当写C语言写多了,自然就喜欢C++了----小话c++(1)

[Mac 10.7.1 Lion x64 Intel-based gcc4.2.1 xcode4.2] Q&#xff1a; 解释下标题吧。 A&#xff1a; 依稀记得&#xff0c;写一个数值绝对值的函数时&#xff0c;写到第三个&#xff0c;实在感觉很痛苦&#xff0c;重复了这么多遍&#xff0c;立刻体会了重载和STL的重要…

c库(下)----小话c语言(18)

[Mac 10.7.1 Lion Intel-based x64 gcc4.2.1 xcode4.2 ] Q&#xff1a; 如何解决abs函数传入一个整形数最小值返回溢出的数&#xff1f; #include <stdio.h> #include <stdlib.h> #include <string.h> #include <limits.h>#define PRINT_D(int…

c语言,有时莫名,有时奇妙----小话c语言(25)

作者&#xff1a;陈曦 日期&#xff1a;2012-8-17 12:53:12 环境&#xff1a;[Mac 10.7.1 Lion Intel i3 支持64位指令 gcc4.2.1 xcode4.2] 转载请注明出处 Q1&#xff1a; 为什么下面的输出不按照代码的顺序显示&#xff1f; #include <stdio.h>#include <uni…

开发实用命令和工具----小话c语言(16)

[Mac 10.7.1 Lion Intel-based x64 gcc4.2.1] Q&#xff1a; 有的时候&#xff0c;记得在某个目录下写过某个变量或者其它什么文本形式的东西&#xff0c;但是后来忘记写在哪个文件里了&#xff0c;怎么找到&#xff1f; A&#xff1a; 这个就需要用到grep命令了。它很强大…

小话层次分析法(AHP)

在目标决策领域&#xff0c;有的决策数据信息是量化的&#xff0c;如一个项目的未来收益、消耗成本等&#xff0c;通过对各种信息进行计算可以做出较好的决策&#xff1b;但有的决策数据信息并不全是数字化的&#xff0c;如项目信息为“这个收益更好”、“这个成本更高”这样的…

小话设计模式(番外一)插件模式

插件&#xff08;Plugin&#xff09;模式向用户提供了一种扩展程序的接口&#xff0c;用户可以在程序本体之外&#xff0c;按照指定接口编写插件来为程序增加功能。 可能实际开发中不太会运用到插件模式&#xff0c;但是它确实我们经常会使用到的一种模式。例如CocosBuilder和…

前言----小话c语言(1)

不知道该怎么开头&#xff0c;不过开头的几个字都写了&#xff0c;就继续写下去吧。 看过很多以大话开头的书籍&#xff0c;觉得也不怎么样&#xff0c;觉得还没达到大话的层次&#xff0c;本人本着谦虚的精神&#xff0c;暂且以小话开头吧&#xff1b;可能读者看完&#xff0c…

Git安装与仓库配置(附带)

Git的安装与仓库配置 前期准备安装与配置安装Git注册账户&#xff1a;环境配置配置用户名与邮箱&#xff1a;生成SSH添加SSH配置仓库仓库建立初始化仓库 提交文件操作&#xff1a; Git 的基本语法总结总结小话 前期准备 下载Git安装包&#xff08;根据需求不同选择安装Window/…