文章目录
前言
地址:aHR0cHM6Ly9mdXd1Lm5oc2EuZ292LmNuL25hdGlvbmFsSGFsbFN0LyMvc2VhcmNoL2RydWctZGlyZWN0b3J5
这个是某个小粉丝私信发的一个网站,过了好久才着手解决,大概看了下,JS加密挺复杂的,零零散散扣了几千行JS还是没扣完整,所以干脆就换个方式,不扣JS了
一、页面分析
1.请求参数加密
主要加密参数是encData和signData,直接搜索一个signData
找到signData的加密位置,下断点调试一下,并改写成自己的方法
signData主要加密逻辑在这里
o.doSignature(i, h, {hash: !0})
其中,i='appCode=T98HPCGN5ZVVQBS8LZQNOAEXVI9GYHKQ&data={"drugType":"1","pageNum":"1","pageSize":"10"}&encType=SM4&signType=SM2×tamp=1606374010&version=1.0.0&key=NMVFVILMKT13GEMD3BKPKCTBOQBPZR2P'
i中的appCode和key是定制,只需改变pageNum、timestamp
encData请求参数加密位置,然后调试进去找主要加密方法
这里主要是t
参数和返回的请求加密数据A(g(l, u), t).toUpperCase()
其中w函数的加密参数e.data.data && JSON.stringify(e.data.data)如下,请求时只需改变pageNum、pageSize即可
'{"q":"","drugLv":"","dosformName":"","drugType":"1","pageNum":1,"pageSize":10}'
A(g(l, u), t).toUpperCase() 函数中的l、u均为定值,不需要管他
2.响应参数encData解密
var n = e.from(t.data.data.encData, "hex")
t.data.data.encData 参数为响应的encData加密数据
var i = function(t, n) {
var i = s.decrypt(n, t)
, r = i[i.length - 1];
return i = i.slice(0, i.length - r),
e.from(i).toString("utf-8")
}(g(l, u), n)
i为解密后的数据
二、修改JS
分析好了加密参数逻辑后,将他们改写成自己的JS方法
1.请求signData加密
添加如下代码
2.请求encData加密
添加如下代码
3.返回encData解密
添加如下代码
4.使用charles拦截并修改JS
将app.bcb0f797.js
下载并添加之前说的几个全局变量,使用charles进行拦截
4.使用Flask+selenium形成自己的加密和解密接口
Flask代码:
import json
import re
from selenium import webdriver
from flask import Flask, request
import requests
options = webdriver.ChromeOptions()
options.add_argument('--headless') # 开启无界面模式
options.add_argument('--disable-gpu') # 禁用显卡
driver = webdriver.Chrome(options=options, executable_path='D:\chromedriver\chromedriver.exe')
driver.get('https://fuwu.nhsa.gov.cn/nationalHallSt/#/search/drug-directory')
app = Flask(__name__)
app.debug = False
def get_sign(sign):
js = """
return get_signData('{}');
""".format(sign)
decrypt_data = driver.execute_script(js)
return decrypt_data
def get_enc(enc):
js = """
return get_enc('{}');
""".format(enc)
decrypt_data = driver.execute_script(js)
return decrypt_data
def get_data(sign,enc,timestamp):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
'Content-Type': 'application/json',
'Accept': 'application/json',
'contentType': 'application/x-www-form-urlencoded',
'sec-ch-ua': '"Chromium";v="86", "\\"Not\\\\A;Brand";v="99", "Google Chrome";v="86"',
'Accept-Language': 'zh-CN,zh;q=0.9',
}
data = {"data": {"data": {
"encData": enc},
"appCode": "T98HPCGN5ZVVQBS8LZQNOAEXVI9GYHKQ", "version": "1.0.0", "encType": "SM4", "signType": "SM2",
"timestamp": int(timestamp),
"signData": sign}}
response = requests.post('https://fuwu.nhsa.gov.cn/ebus/fuwu/api/nthl/api/drug/searchDrug', headers=headers,data=json.dumps(data), verify=False)
# print(response.text)
data = response.json()['data']['data']['encData']
print(data)
js = """
return get_decData('{}');
""".format(data)
decrypt_data = driver.execute_script(js)
return decrypt_data
@app.route('/get_res', methods=['GET'])
def fuwu():
sign_data = request.args.get("sign")
enc_data = request.args.get("enc")
timestamp = re.compile('timestamp=(.*?)&').findall(sign_data)[0]
sign = get_sign(sign_data) # 药品 'appCode=T98HPCGN5ZVVQBS8LZQNOAEXVI9GYHKQ%26data={"drugType":"1","pageNum":"1","pageSize":"10"}%26encType=SM4%26signType=SM2%26timestamp=1606358425%26version=1.0.0%26key=NMVFVILMKT13GEMD3BKPKCTBOQBPZR2P'
enc = get_enc(enc_data) # 药品 '{"q":"","drugLv":"","dosformName":"","drugType":"1","pageNum":1,"pageSize":10}'
decrypt_data = get_data(sign,enc,timestamp)
print(sign,enc,timestamp)
print(decrypt_data)
return decrypt_data
if __name__ == '__main__':
app.run()
请求接口代码:
import requests
headers = {
'sec-ch-ua': '"Chromium";v="86", "\\"Not\\\\A;Brand";v="99", "Google Chrome";v="86"',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Accept-Language': 'zh-CN,zh;q=0.9',
}
page = '1'
params = (
('sign', 'appCode=T98HPCGN5ZVVQBS8LZQNOAEXVI9GYHKQ&data={"drugType":"1","pageNum":"'+page+'","pageSize":"10"}&encType=SM4&signType=SM2×tamp=1606358425&version=1.0.0&key=NMVFVILMKT13GEMD3BKPKCTBOQBPZR2P'),
('enc', '{"q":"","drugLv":"","dosformName":"","drugType":"1","pageNum":'+page+',"pageSize":10}'),
)
response = requests.get('http://127.0.0.1:5000/get_res', headers=headers, params=params)
print(response.text)
for data in response.json()['list']:
print(data)
三、结果
网页数据:
接口数据:
四、小结
又时候碰到JS加密不一定非要跟他死扣,你可能扣个几小时抠出来,可别人早已经把数据都爬完了,所以这种方式挺适合业务上的跟进,如果是想要学习提高自己还是建议不要用这个方法