日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

【JS 逆向百例】有道翻译接口参数逆向

發(fā)布時間:2023/12/10 javascript 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【JS 逆向百例】有道翻译接口参数逆向 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

    • 逆向目標
    • 逆向過程
      • 抓包分析
      • 參數(shù)逆向
    • 完整代碼
      • youdao_encrypt.js
      • youdaofanyi.py


逆向目標

  • 目標:有道翻譯接口參數(shù)
  • 主頁:https://fanyi.youdao.com/
  • 接口:https://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule
  • 逆向參數(shù):
    • Form Data:
      • salt: 16261583727540
      • sign: 151e4b19b07ae410e0e1861a6706d30c
      • bv: 5b3e307b66a6c075d525ed231dcc8dcd

逆向過程

抓包分析

我們在有道翻譯頁面隨便輸入文字,可以看到?jīng)]有刷新頁面,翻譯結果就出來了,由此可以推斷是 Ajax 加載的,打開開發(fā)者工具,選擇 XHR 過濾 Ajax 請求,可以看到有一條 URL 為 https://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule 的 POST 請求,當我們輸入“測試”的時候,他返回的數(shù)據(jù)類似于如下結構:

{"translateResult": [[{"tgt": "test","src": "測試"}]],"errorCode": 0,"type": "zh-CHS2en","smartResult": {"entries": ["", "[試驗] test\r\n", "measurement\r\n"],"type": 1} }

translateResult 是翻譯的結果,smartResult 是智能推薦的其他翻譯,那么這個 URL 就是我們需要的翻譯接口了。

由于是 POST 請求,我們觀察它的 Form Data:

  • i:待翻譯的字符串;
  • from:待翻譯的語言;
  • to:目標語言;
  • lts:時間戳;
  • smartresult 、client、doctype、version、keyfrom:固定值;
  • action:實時翻譯 FY_BY_REALTlME、手動點擊翻譯 FY_BY_CLICKBUTTION;
  • salt、sign、bv 的值每次會改變,需要進一步分析。

參數(shù)逆向

salt、sign、bv 三個加密參數(shù),全局搜索任意一個,搜索結果比較多,依次對比,可以發(fā)現(xiàn) fanyi.min.js 文件第 8969 行左右開始,Form Data 所有的參數(shù)都齊全了,埋下斷點調(diào)試一下,可以看到所有數(shù)據(jù)和最終結果一致,加密的四個參數(shù)都在 r 當中取值,跟蹤 r,往上找可以看到 r = v.generateSaltSign(n);,其中 n 是輸入的待翻譯的字符串:

繼續(xù)跟進 generateSaltSign 函數(shù),點擊跳轉到 r 函數(shù),這里可以看到關鍵的加密代碼:

var r = function(e) {var t = n.md5(navigator.appVersion), r = "" + (new Date).getTime(), i = r + parseInt(10 * Math.random(), 10);return {ts: r,bv: t,salt: i,sign: n.md5("fanyideskweb" + e + i + "Y2FYu%TNSbMCxc3t2u^XT")} };

分析這段關鍵加密代碼:

  • navigator.appVersion 就是 UserAgent

  • bv 的值由 UserAgent 經(jīng)過 MD5 加密得到

  • ts 的值為 13 位時間戳

  • salt 的值由 ts 的值加上一個 0-9 的隨機整數(shù)得到

  • sign 的值由待翻譯的字符串、salt 的值和另外兩個固定的字符串組成,再由 MD5 加密得到最終結果

這個過程比較簡單,可以直接使用 Python 來復現(xiàn):

import time import random import hashlibquery = "待翻譯字符串" user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"lts = str(int(time.time() * 1000)) # 以毫秒為單位的 13 位時間戳 salt = lts + str(random.randint(0, 9)) # 13 位時間戳+隨機數(shù)字,生成 salt 值 sign = "fanyideskweb" + query + salt + "Y2FYu%TNSbMCxc3t2u^XT" # 拼接字符串組成 sign sign = hashlib.md5(sign.encode()).hexdigest() # 將 sign 進行 MD5 加密,生成最終 sign 值 bv = hashlib.md5(user_agent.encode()).hexdigest() # 對 UA 進行 MD5 加密,生成 bv 值

或者直接引用 JS,使用 nodejs 里面的加密模塊 CryptoJS 來進行 MD5 加密,改寫 JS 如下:

// 引用 crypto-js 加密模塊 var CryptoJS = require('crypto-js')function getEncryptedParams(data, ua) {var bv = CryptoJS.MD5(ua).toString(), lts = "" + (new Date).getTime(), salt = lts + parseInt(10 * Math.random(), 10)var sign = CryptoJS.MD5('fanyideskweb'+data+salt+']BjuETDhU)zqSxf-=B#7m').toString()return {bv: bv, lts: lts, salt: salt, sign: sign} }

完整代碼

youdao_encrypt.js

獲取加密參數(shù) salt、sign、bv:

// 引用 crypto-js 加密模塊 var CryptoJS = require('crypto-js')function getEncryptedParams(data, ua) {var bv = CryptoJS.MD5(ua).toString(),lts = "" + (new Date).getTime(),salt = lts + parseInt(10 * Math.random(), 10)var sign = CryptoJS.MD5('fanyideskweb' + data + salt + ']BjuETDhU)zqSxf-=B#7m').toString()return { bv: bv, lts: lts, salt: salt, sign: sign } }// var ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" // var data = "測試" // console.log(getEncryptedParams(data, ua));

youdaofanyi.py

#!/usr/bin/env python3 # -*- coding: utf-8 -*-import time import random import hashlibimport execjs import requeststranslate_url = 'https://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule' user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'def get_translation_result(parameters):headers = {'User-Agent': user_agent,'Host': 'fanyi.youdao.com','Origin': 'https://fanyi.youdao.com','Referer': 'https://fanyi.youdao.com/','X-Requested-With': 'XMLHttpRequest','sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"','Cookie': 'OUTFOX_SEARCH_USER_ID="-1848382357@10.169.0.84"; ___rl__test__cookies=1625907853887; OUTFOX_SEARCH_USER_ID_NCOO=132978720.55854891'}response = requests.post(url=translate_url, headers=headers, data=parameters)result = response.json()['translateResult'][0][0]['tgt']return resultdef get_parameters_by_python(query, translate_from, translate_to):lts = str(int(time.time() * 1000)) # 以毫秒為單位的 13 位時間戳salt = lts + str(random.randint(0, 9)) # 13 位時間戳+隨機數(shù)字,生成 salt 值sign = "fanyideskweb" + query + salt + "Y2FYu%TNSbMCxc3t2u^XT" # 拼接字符串組成 signsign = hashlib.md5(sign.encode()).hexdigest() # 將 sign 進行 MD5 加密,生成最終 sign 值bv = hashlib.md5(user_agent.encode()).hexdigest() # 對 UA 進行 MD5 加密,生成 bv 值parameters = {'i': query,'from': translate_from,'to': translate_to,'smartresult': 'dict','client': 'fanyideskweb','salt': salt,'sign': sign,'lts': lts,'bv': bv,'doctype': 'json','version': '2.1','keyfrom': 'fanyi.web','action': 'FY_BY_REALTlME'}return parametersdef get_parameters_by_javascript(query, translate_from, translate_to):with open('youdao_encrypt.js', 'r', encoding='utf-8') as f:youdao_js = f.read()params = execjs.compile(youdao_js).call('get_params', query, user_agent) # 通過 JavaScript 代碼獲取各個參數(shù)bv = hashlib.md5(user_agent.encode()).hexdigest() # 對 UA 進行 MD5 加密,生成 bv 值parameters = {'i': query,'from': translate_from,'to': translate_to,'smartresult': 'dict','client': 'fanyideskweb','salt': params['salt'],'sign': params['sign'],'lts': params['lts'],'bv': bv,'doctype': 'json','version': '2.1','keyfrom': 'fanyi.web','action': 'FY_BY_REALTlME'}return parametersdef main():query = input('請輸入要翻譯的文字:')# 原始語言,目標語言,默認自動處理translate_from = translate_to = 'AUTO'# 通過 Python 獲取加密參數(shù)或者通過 JavaScript 獲取參數(shù),二選一param = get_parameters_by_python(query, translate_from, translate_to)# param = get_parameters_by_javascript(query, translate_from, translate_to)result = get_translation_result(param)print('翻譯的結果為:', result)if __name__ == '__main__':main()

總結

以上是生活随笔為你收集整理的【JS 逆向百例】有道翻译接口参数逆向的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。