破解另外一家网站的反爬机制 & HMAC 算法

1、背景


今天在爬另外一家网站数据时,想直接从 ajax 接口入手,可是发现这些 request 加了额外参数来防止爬取,即在 request header 里,有一对随机key-value 参数:形如 e931588bc0dfbc5e6323 : c43dfe7cdc49b6318f43907ad4e7d9b69a23719d2e3b7b59799124408aa11cf383f459a4a558af8c64b289b7d974982aad58db705ac6784460733bd21784bde0,故意让你猜不到。python

可是操做了一会,我总结了以下规律:ajax

一、每一个不一样的接口 url,对应不一样的 key ,但这个 key 刷新页面是不会变得。(看来 key 跟 url 有关)算法

二、每一个 key 对应的 value 一直在变。(过后才知道 value 是根据 url 和 post body 共同决定的)json

2、破解


因而经过网站被混淆过的 js ,耐心的打断点分析。api

过程略。安全

3、结果


最后发现:post

key 和 value 都是经过 HMAC(Keyed-Hashing for Message Authentication) 算法得来的。网站

一、HMAC 算法

HMAC 其实就等于咱们日常用的 MD5 / SHA-1 去加 salt 的操做。而采用 HMAC 的好处就是,替代咱们本身的 salt 算法,使得程序算法更标准化,也更安全编码

HMAC 可选择搭配 MD5 / SHA-1 或等等。这里用的是 SHA512url

>>> import hmac
>>> key = b'secret'
>>> message = b'Hello, world!'
>>> h = hmac.new(key, message, digestmod='MD5')
>>> h.hexdigest()
'fa4ee7d173f2d97ee79022d1a7355bcf'

注意:传入的 key 和 message 都是bytes类型,因此str类型须要首先被编码为bytes

二、最终代码

注意:敏感信息被隐藏处理。

import hashlib
import hmac
import requests
import json

host = 'http://example.com'
# request's param - 变化值
uri = '/api/search/example'
data = {
    "cityName": "上海",
    "cityCode": "31",
    # 等等
}

# hmac's secret - 固定值
secret = b'abcdefg'

# calculate key
sign_key = hmac.new(secret, uri.lower().encode(), hashlib.sha512).hexdigest()
header_key = sign_key[10:30]  

# calculate value
sign_value = (uri.lower()+uri.lower() +
              json.dumps(data, separators=(',', ':'), ensure_ascii=False)).lower()
header_value = hmac.new(secret, sign_value.encode(),
                        hashlib.sha512).hexdigest()
# print result
print(header_key, header_value)

而后咱们把算出来的 key 和 value 塞入到每一次请求的 header 里,便可成功调用。

三、坑

上面代码在算 value 的时候,用了 json.dumps(),把中文 上海 转为了 "\u4e0a\u6d77",而不是上海,致使接口一直报错。

解决办法:json.dumps 多传一个参数 ensure_ascii=False

相关文章
相关标签/搜索