文章目录

  • 逆向目标
  • 逆向过程
    • 抓包分析
    • 参数逆向
  • 完整代码
    • youdao_encrypt.js
    • youdaofanyi.py

逆向目标

  • 目标:有道翻译接口参数
  • 主页:https://fanyi.youdao.com/
  • 接口:https://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule
  • 逆向参数:
    • Form Data:

      • salt: 16261583727540
      • sign: 151e4b19b07ae410e0e1861a6706d30c
      • bv: 5b3e307b66a6c075d525ed231dcc8dcd

逆向过程

抓包分析

我们在有道翻译页面随便输入文字,可以看到没有刷新页面,翻译结果就出来了,由此可以推断是 Ajax 加载的,打开开发者工具,选择 XHR 过滤 Ajax 请求,可以看到有一条 URL 为 https://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule 的 POST 请求,当我们输入“测试”的时候,他返回的数据类似于如下结构:

{"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:时间戳;
  • smartresultclientdoctypeversionkeyfrom:固定值;
  • action:实时翻译 FY_BY_REALTlME、手动点击翻译 FY_BY_CLICKBUTTION
  • saltsignbv 的值每次会改变,需要进一步分析。

参数逆向

saltsignbv 三个加密参数,全局搜索任意一个,搜索结果比较多,依次对比,可以发现 fanyi.min.js 文件第 8969 行左右开始,Form Data 所有的参数都齐全了,埋下断点调试一下,可以看到所有数据和最终结果一致,加密的四个参数都在 r 当中取值,跟踪 r,往上找可以看到 r = v.generateSaltSign(n);,其中 n 是输入的待翻译的字符串:

继续跟进 generateSaltSign 函数,点击跳转到 r 函数,这里可以看到关键的加密代码:

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 经过 MD5 加密得到

  • ts 的值为 13 位时间戳

  • salt 的值由 ts 的值加上一个 0-9 的随机整数得到

  • sign 的值由待翻译的字符串、salt 的值和另外两个固定的字符串组成,再由 MD5 加密得到最终结果

这个过程比较简单,可以直接使用 Python 来复现:

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 位时间戳+随机数字,生成 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

获取加密参数 saltsignbv

// 引用 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 位时间戳+随机数字,生成 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 代码获取各个参数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 获取加密参数或者通过 JavaScript 获取参数,二选一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 逆向百例】有道翻译接口参数逆向相关推荐

  1. 【JS 逆向百例】百度翻译接口参数逆向

    文章目录 逆向目标 逆向过程 抓包分析 获取 token 获取 sign 完整代码 baidu_encrypt.js baidufanyi.py 逆向目标 目标:百度翻译接口参数 主页:https:/ ...

  2. 【JS 逆向百例】HN某服务网登录逆向,验证码形同虚设

    声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 文章目录 声明 逆向目标 ...

  3. Python爬虫之Js逆向案例(6)-某道翻译

    Python爬虫之Js逆向案例(6)-有道翻译 声明:某道翻译加密逆向分析仅用于研究和学习,如有侵权,可联系删除 大家好,距离上次分享js逆向案例已经有一个月了,在这期间每次在快要揭秘出来时.整理文章 ...

  4. 【JS 逆向百例】webpack 改写实战,G 某游戏 RSA 加密

    关注微信公众号:K哥爬虫,QQ交流群:808574309,持续分享爬虫进阶.JS/安卓逆向等技术干货! 声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途 ...

  5. 【JS逆向百例】某音乐网分离式 webpack 非 IIFE 改写实战

    关注微信公众号:K哥爬虫,QQ交流群:808574309,持续分享爬虫进阶.JS/安卓逆向等技术干货! 文章目录 声明 逆向目标 逆向过程 抓包分析 参数逆向 webpack 改写 IIFE 传数组 ...

  6. 使用python对在线网易有道翻译接口进行分析及破解js加密

    文章目录 项目目标 温馨提示 项目分析 分析完毕,进行代码模拟加密过程,代码演示 项目目标 对网易有道翻译接口关键参数进行分析,并且进行js加密破解,实质上就是找出网易有道翻译接口对关键参数的加密的详 ...

  7. 【爬虫逆向案例】某道翻译js逆向—— sign解密

    声明:本文只作学习研究,禁止用于非法用途,否则后果自负,如有侵权,请告知删除,谢谢! [爬虫逆向案例]某道翻译js逆向-- sign解密 1.前言 2.步骤 3.源码 4.号外 1.前言 相信各位小伙 ...

  8. 【JS 逆向百例】X球投资者社区 cookie 参数 acw_sc__v2 加密分析

    关注微信公众号:K哥爬虫,持续分享爬虫进阶.JS/安卓逆向等技术干货! 文章目录 声明 逆向目标 抓包分析 加密查找 参数逆向 完整代码 JavaScript 加密代码 Python 测试代码 声明 ...

  9. python有道自动翻译_Python 调用有道翻译接口实现翻译

    最近为了熟悉一下 js 用有道翻译练了一下手,写一篇博客记录一下,也希望能对大家有所启迪,不过这些网站更新太快,可能大家尝试的时候会有所不同. 首先来看一下网页 post 过去的数据 大家不难发现,我 ...

最新文章

  1. IDP申请直到软件上架流程 - iOS
  2. c语言 dll注入,教大家写一个远程线程的DLL注入,其实还是蛮简单的……………………...
  3. (最新最全)windows使用anaconda安装pytorch进行深度学习并使用GPU加速
  4. js仿QQ中对联系人向左滑动、滑出删除按钮的操作
  5. android代码记录日期,Android日期和时间选择器实现代码
  6. IO流(五)__文件的递归、Properties、打印流PrintStream与PrintWriter、序列流SequenceInputStream...
  7. 关于 Python 列表操作,最常见问答Top10
  8. [music]Canon and Gigue in D major
  9. 计算机网络(三)——TCP/IP协议
  10. 解释Linux进程的父子关系,Linux进程管理
  11. SEO内容为王之如何创造伪原创
  12. 设计模式(5)——单例模式
  13. C++中打印可变参数函数输出到控制台
  14. python stm32f401_STM32学习之GPIO配置 (STM32F401ZGT6)
  15. 《奈飞文化准则3:绝对坦诚,才能获得真正高效的反馈》要点及实施建议
  16. Thinkphp中的 I 函数(Thinkphp3.2.3版本)
  17. 路由器交换机:静态路由
  18. 我的天,《扶摇》的海报也太好看了吧
  19. 阿里云高级工程师认证证书终于到手了!
  20. 高通MSM8953 LK阶段配置使用I2C8

热门文章

  1. bzoj 2905 背单词
  2. Guava源码分析——Immutable Collections(4)
  3. 瀑布流插件|jquery.masonry|使用demo
  4. 容斥原理的二进制实现模版
  5. c/c++笔试面试题(4)
  6. Content Provider 基础 之URI
  7. 常见笔顺错误的字_最全汉字书写笔顺规则
  8. windows搜索工具_加快搞定并替代 Windows 10 搜索框搜索文件速度的免费小工具
  9. 运维工程师绩效考核表_IT运维存在问题及改进
  10. linux新的API signalfd、timerfd、eventfd使用说明——eventfd