web认证

关于我正在做的路由器的web认证方式是这样的:

  1. 客户端首先向服务器发送一条不带认证的get。

  2. 服务器返回 Authorization Required, 并且返回的头信息中含有随机数nonce

  3. 客户端根据返回的nonce、用户名密码等计算出一个request发给服务器,并且还会会送一个cnonce用于后续通信

  4. 大致过程如下:


    认证过程
  • 客户端第一次请求,并未包含任何认证信息:


    web认证_第1张图片
    客户端第一次get
  • 服务器返回Authorization Required,同时包含一个nonce:


    web认证_第2张图片
    Authorization Required
  • 客户端发送认证请求,可以看到认证字段中包含了nonce,cnonce,nc,以及responce等参数:


    客户端认证

下面尝试用python模拟这个过程

  1. 获取服务器nonce:
    这个过程由客户端先向服务器发送一条不带认证get,在服务器返回Authorization Required消息时从消息头中获取服务器的nonce参数。代码实现如下:
res = requests.get('http://192.168.80.131')  #模拟第一次get
res.headers['WWW-Authenticate'].rpartition('nonce="')[2][:-1]  #从服务器返回信息头中抽取nonce字段
  1. 根据服务器参数以及用户密码等计算response参数:
    具体算法如下:
    Response = MD5(md5(your user name:relam:passwd):nonce:nc:cnonce:auth:md5('GET:/index.html'))
    详情可见这个博客很清楚:
    http认证
    代码实现如下:
import hashlib
a = hashlib.md5('admin:_00:admin'.encode(encoding='utf-8')).hexdigest()
b = hashlib.md5('GET:/'.encode(encoding='utf-8')).hexdigest()
c = a+":"+nonce+":"+nc+":"+cnonce+":"+"auth:"+b
response = hashlib.md5(c.encode(encoding='utf-8')).hexdigest()
  1. 综合的代码实现:
import requests
import hashlib

res = requests.get(target ip)
nonce = res.headers['WWW-Authenticate'].rpartition('nonce="')[2][:-1]  #得到服务器返回的nonce值
a = hashlib.md5('admin:_00:admin'.encode(encoding='utf-8')).hexdigest()
b = hashlib.md5('GET:/'.encode(encoding='utf-8')).hexdigest()
nc = '00000001'
cnonce = '7d5f2832dfac6bb48b36fd841165be41'
c = a+":"+nonce+":"+nc+":"+cnonce+":"+"auth:"+b
response = hashlib.md5(c.encode(encoding='utf-8')).hexdigest()  #计算应该发送的response
 
url = target url
headers = {
    **************
    "Authorization":"Digest username='admin',realm='_00',nonce='"+nonce+"',uri=taget url,cnonce='7d5f2832dfac6bb48b36fd841165be41',nc=00000001,response='"+response+"',qop='auth'"
    }

data = {
    ***********
    }

res = requests.post(url,headers=headers,data=data)
print(res)

你可能感兴趣的:(web认证)