破解另外一家網站的反爬機制 & 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

相關文章
相關標籤/搜索