HTTP认证的底层技术简析与揭秘

写在前面的话

HTTP认证实现的基础是Web服务器与浏览器之间能够安全地交换类似用户名和密码这样的用户凭证,我们也可以把HTTP认证当作是摘要验证(Digest Authentication),这种预定义方法/标准在HTTP协议中使用了编码技术和MD5加密哈希。在这篇文章中,我们将会跟大家详细讨论一下HTTP认证所采用的技术和标准。为了方便大家的理解,本文将使用我们自己编写的一个php脚本,它可以方便地帮助我们捕获用户名和密码。

使用Base64编码的基本访问认证

在了解基本认证这一部分中,我们将使用base64编码来生成我们的加密字符串,这个字符串中将包含用户名和密码。需要注意的是,我们这里还可以选择使用其他的编码技术,例如URL编码或十六进制编码等等。

在下面给出的这个列子中,我们使用Burpsuite捕捉到了用户请求。我们可以看到,Web页面正在向客户端请求输入认证数据:

我们输入的用户名是“hackingarticles”,密码为“ignite”。

基本认证所采用的请求语句如下:

Value = username:password Encoded Value = base64(Value) Authorization Value = Basic <Encoded Value>

在基本认证过程中,用户名和密码会被组合成一个单独的字符串,并且使用冒号进行分割。

Value = hackingarticles:ignite

接下来,浏览器会用base64来对这个字符串进行编码。

“hackingarticles:ignite”在经过base64编码之后的值即为“aGFja2luZ2FydGljbGVzOmlnbml0ZQ==”。

最终的认证值(Authorization Value)就是“字符串‘Basic’+空格+编码后的值”,Burpsuite捕获的请求如下图所示:

在这个例子中的认证值就是“Basica GFja2luZ2FydGljbGVzOmlnbml0ZQ==”,而这个值将会被发送至服务器端。最后,服务器会解密这个认证值,然后返回用户输入的凭证。

基本认证是非常不安全的,因为这里仅仅只使用了编码技术,而认证值是可以被解码的。为了增强认证的安全性,我们接下来会讨论其他一些安全系数更高的标准。

RFC 2069摘要访问认证

摘要访问认证使用了哈希算法来生成加密之后的结果。RFC2069现在已经过时了,目前广泛使用的是RFC 2617,它是RFC2069的增强版。为了让大家更好地理解RFC 2069所使用的请求语句,我们在下面给出了RFC2069的语句样例:

Hash1=MD5(username:realm:password) Hash2=MD5(method:digestURI) response=MD5(Hash1:nonce:Hash2)

Hash1(username:realm:password)中包含的是用户名和密码的MD5哈希值,其中的“rea1m”可以是服务器端提供的任意字符串,而用户名和密码则由客户端输入。

Hash2(method:digestURI)中包含的是请求方法和摘要地址的MD5哈希值,请求方法(method)可以是GET或POST,具体需要根据页面所使用的请求方法来确定,而摘要地址(digestURI)则是发送请求的页面地址。

response(hash1:nounce:hash2)中的值是最后需要发送给服务器端的字符串,其中包含的是刚才生成的hash1和hash2,以及一个任意字符串nonce,这个nonce字符串由服务器端发送给客户端,且只能使用一次(相当于一次性验证码)。

RFC 2617摘要访问认证

RFC 2617摘要认证同样使用了MD5哈希算法,但是最终哈希值的生成还需要涉及到一些额外的参数。RFC2617的请求语句如下所示:

Hash1=MD5(username:realm:password) Hash2=MD5(method:digestURI) response=MD5(Hash1:nonce:nonceCount:cnonce:qop:Hash2)

与之前一样,Hash1(username:realm:password)中包含的是用户名和密码的MD5哈希值,其中的“rea1m”可以是服务器端提供的任意字符串,而用户名和密码则由客户端输入。

Hash2(method:digestURI)中包含的是请求方法和摘要地址的MD5哈希值,请求方法(method)可以是GET或POST,具体需要根据页面所使用的请求方法来确定,而摘要地址(digestURI)则是发送请求的页面地址。

response((Hash1:nonce:nonceCount:cnonce:qop:Hash2)中的值是最后需要发送给服务器端的字符串,其中包含的是刚才生成的hash1和hash2以及一些额外参数。如果你想了解这些额外参数的话,可以参考微软发布的技术文章(点击文末的阅读原文查看)。

接下来,我们会给大家介绍RFC 2617的工作机制。首先,Web页面会向客户端请求输入数据:

我们输入的用户名为“guest”,密码同样为“guest”。在Burpsuite的帮助下,我们捕获到了浏览器发送的请求以及所有的参数,现在我们就可以用其他哈希计算工具来生成输入数据的哈希值,然后再用我们自己生成的数据来与捕获到的哈希数据进行对比。

我们捕获到的哈希值以及相应参数如下所示:

realm=”Hacking Articles”,nonce=”58bac26865505″, uri=”/auth/02-2617.php”, opaque=”8d8909139750c6bd277cfe1388314f48″,qop=auth, nc=00000001, cnonce=”72ae56dde9406045″ , response=”ac8e3ecd76d33dd482783b8a8b67d8c1″, Hash1 Syntax=MD5(username:realm:password) hash1 = md5(guest:Hacking Articles:guest)

我们自己用工具计算出的MD5哈希值如下所示:

guest:Hacking Articles:guest Hash:2c6165332ebd26709360786bafd2cd49

GET:/auth/02-2617.php Hash:b6a6df472ee01a9dbccba5f5e6271ca8

response =MD5(2c6165332ebd26709360786bafd2cd49:58bac26865505:00000001:72ae56dde9406045:auth:b6a6df472ee01a9dbccba5f5e6271ca8) Hash:ac8e3ecd76d33dd482783b8a8b67d8c1

没错,我们通过Hash Calculator(哈希计算器)自行计算出的哈希值与我们通过Burpsuite捕获到的哈希值是完全一样的。

最后,服务器会解密response的值,输出结果如下图所示:

总结

我们在这篇文章中跟大家分析了当前HTTP认证的底层加密技术,希望这些内容可以帮助到各位白帽子,给大家在挖洞的过程中提供灵感。

原文发布于微信公众号 - FreeBuf(freebuf)

原文发表时间:2017-03-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏小尘哥的专栏

springboot使用properties定义短信模板

通常我们做开发时候会遇到短信发送邮件发送之类的需求,发送内容往往会由客户提供一个模板,如果我们是在程序里拼接字符串来搞定这个模板,很明显是一种坑队友的做法。一般...

1123
来自专栏用户2442861的专栏

JSP常用跳转方式

http://blog.csdn.net/wanghuan203/article/details/8836326#comments

2811
来自专栏移动端开发

Swift 2.0 单例的用法

单例我们项目中是很常用的,今天刚学了在swift中怎么写单例和调用单例。下面我们简单的介绍一下。我们先看看Swift单例的写法: import UIKit c...

1958
来自专栏沈唁志

在Linux中vim的用法

2122
来自专栏ascii0x03的安全笔记

Linux下ls命令显示符号链接权限为777的探索

Linux下ls命令显示符号链接权限为777的探索                                                ——深入ls、...

9845
来自专栏源哥的专栏

基于linux的嵌入IPv4协议栈的内容过滤防火墙系统(7)-尚未解决的问题

1。因为我们无法得到对rar文件的数据进行压缩的方法,所以我们无法得到rar文件里面的内容,只能得到rar文件里面的目录名和

811
来自专栏大内老A

ASP.NET Web API自身对CORS的支持: CORS授权检验的实施

通过《EnableCorsAttribute特性背后的故事》我们知道:由CorsPolicyProvider提供的CorsPolicy表示目标Action采用的...

19910
来自专栏Google Dart

Dart服务器端 shelf包 原

handler是处理shelf.Request并返回shelf.Response的任何函数。它可以处理请求本身 - 例如,在文件系统上查找请求的URI的静态文件...

2941
来自专栏Java帮帮-微信公众号-技术文章全总结

Java开发必会框架Struts2第一天

一、框架概述 1、框架的意义与作用: 所谓框架,就是把一些繁琐的重复性代码封装起来,使程序员在编码中把更多的经历放到业务需求的分析和理解上面。 特点:封装了很多...

3648
来自专栏CSDN技术头条

使用 Dubbo 搭建一个简单的分布式系统

随着阿里巴巴开源的高性能分布式 RPC 框架 Dubbo 正式进入 Apache 孵化器,Dubbo 又火了一把。本文作为 Dubbo 系列开端,先教大家使用 ...

1692

扫码关注云+社区

领取腾讯云代金券