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

逆向目标
- 目标:有道翻译接口参数
- 主页:https://fanyi.youdao.com/
- 接口:https://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule
- 逆向参数:
- Form Data:
salt: 16261583727540sign: 151e4b19b07ae410e0e1861a6706d30cbv: 5b3e307b66a6c075d525ed231dcc8dcd
- Form Data:
逆向过程
抓包分析
我们在有道翻译页面随便输入文字,可以看到没有刷新页面,翻译结果就出来了,由此可以推断是 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:时间戳;smartresult、client、doctype、version、keyfrom:固定值;action:实时翻译FY_BY_REALTlME、手动点击翻译FY_BY_CLICKBUTTION;salt、sign、bv的值每次会改变,需要进一步分析。

参数逆向
salt、sign、bv 三个加密参数,全局搜索任意一个,搜索结果比较多,依次对比,可以发现 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就是 UserAgentbv的值由 UserAgent 经过 MD5 加密得到ts的值为 13 位时间戳salt的值由ts的值加上一个 0-9 的随机整数得到sign的值由待翻译的字符串、salt的值和另外两个固定的字符串组成,再由 MD5 加密得到最终结果
这个过程比较简单,可以直接使用 Python 来复现:
import time
import random
import hashlib
query = "待翻译字符串"
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
获取加密参数 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 hashlib
import execjs
import requests
translate_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 result
def 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" # 拼接字符串组成 sign
sign = 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 parameters
def 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 parameters
def 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 逆向百例】有道翻译接口参数逆向的更多相关文章
- .net core 和 WPF 开发升讯威在线客服系统:调用有道翻译接口实现实时自动翻译的方法
业余时间用 .net core 写了一个在线客服系统.并在博客园写了一个系列的文章,写介绍这个开发过程. 我把这款业余时间写的小系统丢在网上,陆续有人找我要私有化版本,我都给了,毕竟软件业的初衷就是免 ...
- Python爬虫有道翻译接口
import urllib.request import urllib.parse import json import hashlib from datetime import datetime i ...
- Python反编译调用有道翻译(附完整代码)
网易有道翻译是一款非常优秀的产品,他们的神经网络翻译真的挺无敌.无奈有道客户端实在是太难用了,而且在某些具体场景 (比如对网站进行批量翻译) 无法使用,而有道的云服务又特别的贵,一般人是无法 ...
- 利用有道翻译Api实现英文翻译功能
有道翻译提供了翻译和查词的数据接口.通过数据接口,您可以获得一段文本的翻译结果或者查词结果. 通过调用有道翻译API数据接口,您可以在您的网站或应用中更灵活地定制翻译和查词功能. 第一步: ...
- 有道翻译-JS逆向-api调用
简单方法 -调用开源api 这个比较简单四行代码就可以搞定,先放代码: 1 import requests 2 while True: 3 input_data = input('请输入你要翻译的数据 ...
- JS解密入门——有道翻译
JS解密入门——有道翻译 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的人,却不知道如何去学习更加高深的知识.那么针对这 ...
- 有道翻译js加密参数分析
平时在渗透测试过程中,遇到传输的数据被js加密的比较多,这里我以有道翻译为例,来分析一下它的加密参数 前言 这是有道翻译的界面,我们随便输入一个,抓包分析 我们发现返回了一段json的字符串,内容就是 ...
- Python爬虫教程-16-破解js加密实例(有道在线翻译)
python爬虫教程-16-破解js加密实例(有道在线翻译) 在爬虫爬取网站的时候,经常遇到一些反爬虫技术,比如: 加cookie,身份验证UserAgent 图形验证,还有很难破解的滑动验证 js签 ...
- Java接口测试之使用有道翻译API
写接口测试框架,找了有道翻译API来当测试数据 package com.httpGetTest; import java.beans.Encoder; import java.net.URLEncod ...
- python爬虫-有道翻译-js加密破解
有道翻译-js加密破解 这是本地爬取的网址:http://fanyi.youdao.com/ 一.分析请求 我们在页面中输入:水果,翻译后的英文就是:fruit.请求携带的参数有很多,先将参数数据保存 ...
随机推荐
- 挖掘优质短视频超百万条,火山引擎DataLeap助力电商平台生态治理
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 在人们的日常生活中,网购已经成为人们生活中不可或缺的购物形式. 根据<中国社交电商行业发展白皮书( ...
- Solon v1.9.1,让 Java 快速启动
相对于 Spring Boot 和 Spring Cloud 的项目: 启动快 5 - 10 倍. (更快) qps 高 2- 3 倍. (更高) 运行时内存节省 1/3 ~ 1/2. (更少) 打包 ...
- Java基础知识整理,驼峰规则、流程控制、自增自减
写在开头 本文接着上一篇文章续写哈.[Java基础知识整理,注释.关键字.运算符](https://blog.csdn.net/qq_43506040/article/details/13563332 ...
- Java内部类详解--成员内部类,局部内部类,匿名内部类,静态内部类
一.内部类基础 在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类.广泛意义上的内部类一般来说包括这四种:成员内部类.局部内部类.匿名内部类和静态内部类.下面就先来了解一 ...
- SpringCloud学习 系列十、服务熔断与降级(2-方法级别服务降级)
系列导航 SpringCloud学习 系列一. 前言-为什么要学习微服务 SpringCloud学习 系列二. 简介 SpringCloud学习 系列三. 创建一个没有使用springCloud的服务 ...
- 十六、企业级私有仓库harbor
系列导航 一.docker入门(概念) 二.docker的安装和镜像管理 三.docker容器的常用命令 四.容器的网络访问 五.容器端口转发 六.docker数据卷 七.手动制作docker镜像 八 ...
- 扒一扒迅雷11新功能——6T云盘功能、极致传输、高清播放、跨端同步
云盘功能 极致传输 高清播放 跨端同步
- java进阶(30)--Hashtable集合与Properties集合
一.Hashtable简介 1.HashMap与Hashtable区别 Hashtable的key与value均不能为空,而HashMap均可以 2.Hashtable方法带有Synchronized ...
- [转帖]Linux 下rsync命令详细整理
https://blog.csdn.net/weixin_44052462/article/details/116134761 rsync是一个功能非常强大的工具,其命令也有很多功能特色选项,我们下面 ...
- [转帖]Nginx中absolute_redirect、port_in_redirect配置简述
一.背景: 我们在访问nginx代理下的项目前端页面时,经常会有访问链接最末尾带不带'/'的问题,当我们访问http://xxxx/home时,如果匹配不到location,会自动加上端口port以及 ...