破解另一家網站的反爬機制 & HMAC 算法


零、寫在前面


本文涉及的反爬技術,僅供個人技術學習,禁止並做到:

  • 干擾被訪問網站的正常運行
  • 抓取受到法律保護的特定類型的數據或信息
  • 搜集到的數據禁止傳播、交給第三方使用、或者牟利
  • 如有可能,在爬到數據后24小時候內刪除

具體可參考 2019年5月28號 頒布的 《數據安全管理辦法(征求意見稿)》

一、背景


今天在爬另一家網站數據時,想直接從 ajax 接口入手,但是發現這些 request 加了額外參數來防止爬取,即在 request header 里,有一對隨機key-value 參數:形如 e931588bc0dfbc5e6323 : c43dfe7cdc49b6318f43907ad4e7d9b69a23719d2e3b7b59799124408aa11cf383f459a4a558af8c64b289b7d974982aad58db705ac6784460733bd21784bde0,故意讓你猜不到。

但是操作了一會,我總結了如下規律:

1、每個不同的接口 url,對應不同的 key ,但這個 key 刷新頁面是不會變得。(看來 key 跟 url 有關)

2、每個 key 對應的 value 一直在變。(事后才知道 value 是根據 url 和 post body 共同決定的)

二、破解


於是通過網站被混淆過的 js ,耐心的打斷點分析。

過程略。

三、結果


最后發現:

key 和 value 都是通過 HMAC(Keyed-Hashing for Message Authentication) 算法得來的。

1、HMAC 算法

HMAC 其實就等於我們平常用的 MD5 / SHA-1 去加 salt 的操作。而采用 HMAC 的好處就是,替代我們自己的 salt 算法,使得程序算法更標准化,也更安全

HMAC 可選擇搭配 MD5 / SHA-1 或等等。這里用的是 SHA512

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

注意:傳入的 key 和 message 都是bytes類型,所以str類型需要首先被編碼為bytes

2、最終代碼

注意:敏感信息被隱藏處理。

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 里,即可成功調用。

3、坑

上面代碼在算 value 的時候,用了 json.dumps(),把中文 上海 轉為了 "\u4e0a\u6d77",而不是上海,導致接口一直報錯。

解決辦法:json.dumps 多傳一個參數 ensure_ascii=False


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM