一、说明

web用户认证,最开始是get提交+把用户名密码存放在客户端的cookie中的形式;在意识到这样不安全之后逐渐演变成了post提交+把用户凭证放到了服务端的session中的形式(当然sessionid还在cookie中)。

不过其实最初给http设计的认证方式,既不是“get+cookie”也不是“post+session”,而是Basic和Digest。但Basic和Digest并不流行我想主要是因为麻烦,一是说Basic和Digest使用的Authorization头并不会被浏览器自动发往服务器,二是说对于Digest计算很麻烦。

二、Basic认证形式

2.1 Basic认证请求示例

请求示例如下,主要是Authorization头(位置不重要,http头一般都不分先后)

  1. GET /GetDeviceInfo HTTP/1.1
  2. Host: 192.168.220.128
  3. Authorization: Basic YWRtaW46MTIzNDU2
  4. User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:60.0) Gecko/20100101 Firefox/60.0
  5. Accept-Encoding: gzip, deflate
  6. Accept: */*
  7. Cache-Control: no-cache
  8. Cookie: Secure
  9. Connection: close

2.2 Basic认证计算方法

前边请求Authorization头的YWRtaW46MTIzNDU2,实际上是用户名admin密码123456使用以下计算方法得到:

  1. base64(username:password)

Python计算代码如下:

  1. import base64
  2.  
  3. def get_basic_authorization_header_value(username,password):
  4. # base64编码前后都(要)是字节码形式
  5. authorization_value = base64.b64encode((f"{username}:{password}").encode()).decode()
  6. authorization_header_value = f"Basic {authorization_value}"
  7. return authorization_header_value

三、Digest认证形式

3.1 Digest认证请求示例

  1. GET /GetDeviceInfo HTTP/1.1
  2. Host: 192.168.220.128
  3. User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:60.0) Gecko/20100101 Firefox/60.0
  4. Authorization: Digest username="admin",realm="TVT API Test Tool",nonce="d4f95e85dc5a39a4914db61b67878f5b",uri="GetDeviceInfo",algorithm="MD5",cnonce="d4f95e85dc5a39a4914db61b67878f5b",nc=00000001,qop="auth",response="1cc4cf126d3c4a70d2de34c5d8c2943c"
  5. Accept-Encoding: gzip, deflate
  6. Accept: */*
  7. Cache-Control: no-cache
  8. Cookie: Secure
  9. Connection: close

username----系统用户名;客户端自行填充

realm----领域;服务端通过WWW-Authenticate头返回内容可以自己随便定,但其目的是用于提示客户端当前是什么系统,所以规范来说应类似于“myhost@testrealm.com”的形式。

nonce----服务端通过WWW-Authenticate头返回的随机数

uri----请求接口或资源(似乎规范来说应用GET或POST后的一样,上边例子中少了/是因为服务端没按规范实现)

algorithm----后边response用的计算方法

cnonce----client nonce,客户端生成的随机数

nc----nonce count,用于标识进行请求的次数。(但你一直不变服务端也不会管你对不对)

qop----quality of protection,进一步限定response的计算方法,服务端通过WWW-Authenticate头返回。

response----认证最主要的值,前面各字段除algorithm外全要参与该值的计算。

3.2 Digest认证计算方法

在最开始的RFC 2069中规定response计算方法如下:

  1. HA1 = MD5(username:realm:password)
  2. HA2 = MD5(method:uri)
  3. response = MD5(HA1:nonce:HA2)

随后的RFC 2617对计算方法进行了增强,规定计算方法如下(当algorithm值为MD5或未指定、qop未指定时等同RFC 2069):

  1. # HA1部分
  2. # 当algorithm值为"MD5"或未指定时,HA1计算方法如下
  3. HA1 = MD5(username:realm:password)
  4. # 当algorithm值为"MD5-sess"时,HA1计算方法如下
  5. HA1 = MD5(MD5(username:realm:password):nonce:cnonce)
  6.  
  7. # HA2部分
  8. # 当qop值为"auth"或未指定时,HA2计算方法如下
  9. HA2 = MD5(method:uri)
  10. # 当qop值为"auth-int"时,HA2计算方法如下;entityBody是指整个body(?)
  11. HA2 = MD5(method:uri:MD5(entityBody))
  12.  
  13. # response部分
  14. # 当qop值为"auth"或"auth-int"时,response计算方法如下
  15. response = MD5(HA1:nonce:nonceCount:cnonce:qop:HA2)
  16. # 当qop未指定时,response计算方法如下
  17. response = MD5(HA1:nonce:HA2)

Python计算代码如下:

  1. import hashlib
  2.  
  3. # body初始值不要是None,不然下边encode时会报错
  4. def get_basic_authorization_header_value(username, password, uri, method, realm, nonce, nc, cnonce, algorithm=None, qop=None, body=""):
  5. response_value = calc_digest_response_value(username, password, uri, method, realm, nonce, nc, cnonce, algorithm, qop, body)
  6. authorization_header_value = f'Digest username="{username}",realm="{realm}",nonce="{nonce}",uri="{uri}",algorithm="{algorithm}",cnonce="{cnonce}",nc={nc},qop="{qop}",response="{response_value}"',
  7. return authorization_header_value
  8.  
  9. def calc_digest_response_value(username, password, uri, method, realm, nonce, nc, cnonce, algorithm=None, qop=None, body=""):
  10. # HA1部分
  11. # 当algorithm值为"MD5"或未指定时,HA1计算方法如下
  12. if algorithm == "MD5" or algorithm == "" or algorithm is None:
  13. HA1 = hashlib.md5((f"{username}:{realm}:{password}").encode()).hexdigest()
  14. # 当algorithm值为"MD5-sess"时,HA1计算方法如下
  15. elif algorithm == "MD5-sess":
  16. HA1 = hashlib.md5((f"{username}:{realm}:{password}").encode()).hexdigest()
  17. HA1 = hashlib.md5((f"{HA1}:{nonce}:{cnonce}").encode()).hexdigest()
  18. else:
  19. response_value = '"the value of algorithm must be one of "MD5"/"MD5-sess"/""/None'
  20. return response_value
  21.  
  22. # HA2部分
  23. # 当qop值为"auth"或未指定时,HA2计算方法如下
  24. if qop == "auth" or qop == "" or qop is None:
  25. HA2 = hashlib.md5((f"{method}:{uri}").encode()).hexdigest()
  26. # 当qop值为"auth-int"时,HA2计算方法如下;entityBody是不是指整个body我其实不太确定
  27. elif qop == "auth-int":
  28. HA2 = hashlib.md5((f"{body}").encode()).hexdigest()
  29. HA2 = hashlib.md5((f"{method}:{uri}:{HA2}").encode()).hexdigest()
  30. else:
  31. response_value = '"the value of qop must be one of "auth"/"auth-int"/""/None'
  32. return response_value
  33.  
  34. # response部分
  35. # 当qop值为"auth"或"auth-int"时,response计算方法如下
  36. if qop == "auth" or qop == "auth-int":
  37. response_value = hashlib.md5((f"{HA1}:{nonce}:{nc}:{cnonce}:{qop}:{HA2}").encode()).hexdigest()
  38. # 当qop未指定时,response计算方法如下
  39. elif qop == "" or qop is None:
  40. response_value = hashlib.md5((f"{HA1}:{nonce}:{HA2}").encode()).hexdigest()
  41. else:
  42. response_value = "unknown error"
  43. return response_value

参考:

https://en.wikipedia.org/wiki/Digest_access_authentication

https://tools.ietf.org/html/rfc2069

https://tools.ietf.org/html/rfc2617

HTTP Basic和Digest认证介绍与计算的更多相关文章

  1. HTTP认证模式:Basic and Digest Access Authentication

    一. Basic 认证 客户端以“ : ”连接用户名和密码后,再经BASE64编码( Base64 Content-Transfer-Encoding )通过Authorization请求头发送该密文 ...

  2. http 登录Digest认证相关知识

    Digest access authentication https://en.wikipedia.org/wiki/Digest_access_authentication Digest acces ...

  3. 【ASP.NET Web API2】Digest认证

    Digest摘要认证 对于Basic认证方案来说,被传输的认证凭证仅仅采用Base64编码,所以包含密码的认证凭证基本上可以视为明文传输.Digest认证在此基础上进行了改善,在一定程度上提高了安全系 ...

  4. OAuth2.0认证介绍

    OAuth2.0鉴权 返回 目录 [隐藏] 1 腾讯微博OAuth2.0认证介绍 2 获取accesstoken的两种方式 2.1 1.Authorization code grant 2.1.1 第 ...

  5. 批量检测GoAhead系列服务器中Digest认证方式的服务器弱口令

    最近在学习用python写爬虫工具,某天偶然发现GoAhead系列服务器的登录方式跟大多数网站不一样,不是采用POST等方法,通过查找资料发现GoAhead是一个开源(商业许可).简单.轻巧.功能强大 ...

  6. 使用crypt配置Basic Auth登录认证

    简介 Basic Auth用于服务端简单的登录认证,通常使用服务器Nginx.Apache本身即可完成.比如我们要限定某个域名或者页面必须输入用户名.密码才能登录,但又不想使用后端开发语言,此时Bas ...

  7. 本文将介绍“数据计算”环节中常用的三种分布式计算组件——Hadoop、Storm以及Spark。

    本文将介绍“数据计算”环节中常用的三种分布式计算组件——Hadoop.Storm以及Spark. 当前的高性能PC机.中型机等机器在处理海量数据时,其计算能力.内存容量等指标都远远无法达到要求.在大数 ...

  8. 任务31:课时介绍 & 任务32:Cookie-based认证介绍 &任务33:34课 :AccountController复制过来没有移除[Authorize]标签

    任务31:课时介绍 cookie-based网站这边的认证 jwt基于移动端和前后端分离的项目,jwt有一些独特的优势 jwt在asp.net core中的实现机制,了解实现机制并进行扩展.比如非标准 ...

  9. 接口开发---basic auth接口认证

    开发中遇到了basic auth来认证的案例,这里总结一下: Basic Auth简单点说明就是每次请求API时都提供用户的username和password.[base64encode(userna ...

随机推荐

  1. Java EE开发技术课程第五周(Applet程序组件与AJAX技术)

    1.Applet程序组件 1.1.定义: Applet是采用Java编程语言编写的小应用程序,该程序可以包含在HTML(标准通用标记语言的一个应用)页中,与在页中包含图像的方式大致相同.含有Apple ...

  2. (纯干货)最新WEB前端学习路线汇总初学者必看

    Web前端好学吗?这是很多web学习者常问的问题,想要学习一门自己从未接触过的领域,事先有些了解并知道要学的内容,对接下来的学习会有事半功倍的效果.在当下来说web前端开发工程师可谓是高福利.高薪水的 ...

  3. 5.JAVA基础复习——JAVA中的static关键字作用与用法

    static关键字: 特点: 1.static是一个修饰符,用于修饰成员.(成员变量,成员函数)static修饰的成员变量 称之为静态变量或类变量. 2.static修饰的成员被所有的对象共享. 3. ...

  4. 第十七节 Cookie基础与应用

    什么是cookie:其实就是页面用来保存信息:比如,自动登录.记住用户名 cookie的特性:(以域名为单位的) 同一个网站(同一个域名)中所有页面共享一套cookie 数量.大小有限,跟浏览器有关, ...

  5. iOS进阶之正则表达式

    最近一直在弄正则表达式,于是在这里整理一下,便于日后查阅. 1.常用符号 ^:字符串的开始 $:字符串的结束 *:表示零个或若干个 ?:表示零个或一个 +:表示一个或若干个 | :表示 或 操作 . ...

  6. python 识别图片上的数字

    https://blog.csdn.net/qq_31446377/article/details/81708006 ython 3.6 版本 Pytesseract 图像验证码识别 环境: (1) ...

  7. JavaScript实现自定义日期时间

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. PHP操作RabbitMQ的类 exchange、queue、route kye、bind

    RabbitMQ是常见的消息中间件.也许是还是不够了解的缘故,感觉功能还好吧. 讲到队列,大家脑子里第一印象是下边这样的. P生产者推送消息-->队列-->C消费者取出消息 结构很简单,但 ...

  9. bzoj 3473 字符串 - 后缀数组 - 树状数组

    题目传送门 传送门 题目大意 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串 先用奇怪的字符把所有字符串连接起来. 建后缀树,数每个节点的子树内包含多少属 ...

  10. Spring HATEOAS的简单认识

    HATEOAS: 超媒体作为应用程序状态引擎(HATEOAS)是REST应用程序体系结构的一个组件,它将其与其他网络应用程序体系结构区分开来. 使用HATEOAS,客户端与网络应用程序交互,其应用程序 ...