某道翻译逆向

news2024/12/23 10:28:49

文章目录

  • 前文
  • crypto模块
  • 分析
  • 完整代码
  • 结尾

前文

本文章中所有内容仅供学习交流,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除!

crypto模块

Crypto是加密的简称,它是一种将信息加密成不可读的形式,以防止未经授权的用户访问和使用这些信息的技术。它是一种安全技术,可以帮助保护数据和隐私,并确保只有授权的用户可以访问和使用这些信息。

Crypto的用途主要是保护数据,防止未经授权的用户访问和使用这些数据,以及防止攻击者窃取数据。它可以用于保护网络流量、保护数据库、保护文件、保护电子邮件以及保护网络设备等。此外,它还可以用于保护网络服务器和网络设备的配置。

Crypto的历史可以追溯到古希腊时期,当时古希腊人使用一种称为“秘密写作”的技术来进行加密通信。随着技术的发展,加密技术也发生了很大的变化。20世纪50年代,数字加密技术开始出现,它可以用来加密电子消息,以防止未经授权的用户访问和使用这些消息。20世纪90年代,加密技术的发展迅速,包括公钥加密、数字签名、数字证书和数字认证等技术。

未来,随着科技的发展,Crypto也将不断发展,它正在变得越来越安全,越来越可靠。未来,Crypto将被用于更多的安全应用,如云安全、物联网安全、虚拟现实安全以及人工智能安全等,以帮助保护数据和隐私,并确保只有授权的用户可以访问和使用这些信息。

在 Node.js 中,crypto 模块是内置的,无需额外安装。可以直接使用它来进行加密和解密操作。

要在 Node.js 中使用 crypto 模块,导入模块crypto:

const crypto = require('crypto');

然后,可以使用该模块提供的各种方法进行加密、解密、哈希等操作。例如,以下是使用 crypto 模块进行 AES 加密和解密的示例:

const crypto = require('crypto');  
  
const algorithm = 'aes-256-cbc';  
const key = crypto.randomBytes(32);  
const iv = crypto.randomBytes(16);  
  
const encrypt = (text) => {  
  const cipher = crypto.createCipheriv(algorithm, key, iv);  
  let encrypted = cipher.update(text);  
  encrypted = Buffer.concat([encrypted, cipher.final()]);  
  return { iv: iv.toString('hex'), encryptedData: encrypted.toString('hex') };  
};  
  
const decrypt = (data) => {  
  const decipher = crypto.createDecipheriv(algorithm, key, Buffer.from(data.iv, 'hex'));  
  let decrypted = decipher.update(Buffer.from(data.encryptedData, 'hex'));  
  decrypted = Buffer.concat([decrypted, decipher.final()]);  
  return decrypted.toString();  
};  
  
const text = 'Hello, World!';  
const encryptedData = encrypt(text);  
console.log('Encrypted:', encryptedData);  
const decryptedText = decrypt(encryptedData);  
console.log('Decrypted:', decryptedText);

在这个示例中,我们使用 crypto.randomBytes() 方法生成随机的密钥和初始化向量(IV)。然后,我们使用 crypto.createCipheriv() 方法创建一个加密器,并使用 update() 和 final() 方法对文本进行加密。最后,我们使用 crypto.createDecipheriv() 方法创建一个解密器,并使用 update() 和 final() 方法对加密后的数据进行解密。

分析

老规矩,f12打开开发者抓包,接着在输入框里面输入‘加油’,‘努力’,然后找到这俩个包,发现数据加密了,对比查询参数,sign和mysticTime不同,mysticTime是一串数字,估计是时间戳,重点在sign参数身上,然后还有一个响应数据的解密。那我们先进行数据的解密。
在这里插入图片描述

在这里插入图片描述
我们打开全局搜索,搜索JSON.parse,为什么搜索JSON.parse

JSON.parse() 通常用于与服务端交换数据。

在接收服务器数据时一般是字符串。

我们可以使用 JSON.parse() 方法将数据转换为 JavaScript 对象。

服务器返回加密的数据,那肯定要在客户端转换为javascript对象。直接全局搜索,搜索到后我们一个个去调试。发现返回的加密数据,那我们接着往下走。
在这里插入图片描述
最终我们找到了解密的地方,tt[“a”].decodeData方法中传入了三个值,o是加密的值,za[“a”].state.text.decodeKey和za[“a”].state.text.decodeIv暂且不知。那我们接着进入方法中。
在这里插入图片描述
进入方法后,这段代码使用AES-128-CBC算法对一个密文进行解密,并返回解密后的明文。其中,e.alloc 方法用于分配内存或处理密钥和初始化向量,r.a.createDecipheriv 方法用于创建解密器对象,update 方法用于解密密文,而 final 方法用于完成解密操作并返回结果。那我们可以用python或者js调用解密的库来实现解密。
在这里插入图片描述
我们发现j(o)函数中对密钥和偏移量md5加密了,如果用过js中的crypto库,就会发现他们调用了crypto库,那我们只需同样使用该库即可。
在这里插入图片描述

返回数据解密完成了,接下来就开始对参数进行逆向。
我们随便选一个查询参数,在全局搜索里面搜索,这里我们选择pointParam,找到了许多参数,其中就含有sign,我们打上断点调试。
在这里插入图片描述
sign的值是有w(o,e)方法生成的,其中o是13位的时间戳,e是个固定值,大家可以多输入几个值,确定e是不是固定值。接着我们进入w方法。w方法中又调用了A方法,并传入了一个值,A方法用md5加密,那们接下来就简单了,构造一个参数传进去就行,这里要注意一下,不要把参数搞错了,t是固定值,e为时间戳,这跟开始的参数是不同的。
在这里插入图片描述
到这里分析已经完成了,接下来是完整代码。

完整代码

js代码

Crypto = require('crypto')

// 数据解密
const md5 = (data) => {
    return Crypto.createHash('md5').update(data).digest();
}


function maindata(data) {
    var keys = "ydsecret://query/key/B*RGygVywfNBwpmBaZg*WT7SIOUP2T0C9WHMZN39j^DAdaZhAnxvGcCY6VYFwnHl"
    var ivs = "ydsecret://query/iv/C@lZe2YzHtZ2CYgaXKSVfsb7Y4QWHjITPPZ0nQp87fBeJ!Iv6v^6fvi2WN@bYpJ4"
    const a = Buffer.alloc(16, md5(keys))
        , c = Buffer.alloc(16, md5(ivs))
        , i = Crypto.createDecipheriv("aes-128-cbc", a, c);
    let s = i.update(data, "base64", "utf-8");
    return s += i.final("utf-8")
}

data = 'Z21kD9ZK1ke6ugku2ccWu4n6eLnvoDT0YgGi0y3g-v0B9sYqg8L9D6UERNozYOHqzDTqUrPJE2TWlFtwSVd3-kG1-JpvlRA2Qhnls_wBD3PYWH5mSQncH5ifU4jXxRvdmhe-m4-11dpTv6TStIUXUHiwbBRaWnsY-H8ixy4t-NVozh2RwjOPkc_N8NhTmqKv7wC2xB2OcF3ksgcqJeH-xdDmEUOzteUiuiWZU3GMqA2xJS9z7lxOGUwKssRSzZf0PnmtU2B5KN4W9REPVnczo4EmZavK_ck7emRmkUvj1ZbTaJE8qaUtvOqA5xpZTbX4HXDDy34H9nMp9mNoNdyTOS3S55h9lZCtiWjejwoTYXBmToyLW-SfzgiWt0ypPGosZ14HP7ittBS_rF97fAPTKwuc_WVYvSsIljBfGMU4p4VzbCCNW_ycRJruEto3e0XOfZKN7JS84jCEqwGScheXypOJQ27bTTSxcbsh-cQu1MPwj6yRO-Cumx6za1lTaHg5ON4kzgwA3nBe6uS5o8qJskRHSdVrXgdeZfWpkSphRVjY9QBm-yBHbFCIfISmnOUk'
console.log(maindata(data))

// 参数加密
function A(e) {
    return Crypto.createHash("md5").update(e.toString()).digest("hex")
}

function encryptSign(t){

    var s = 'client=fanyideskweb&mysticTime='+t+'&product=webfanyi&key='+'fsdsogkndfokasodnaso'
    return A(s)
}

const t = (new Date).getTime();
console.log(encryptSign(t))

python代码


import requests
import subprocess
from functools import partial

subprocess.Popen = partial(subprocess.Popen, encoding='utf-8')
import execjs
import time

with open('js.js', 'r', encoding='utf-8') as f:
    js_code = f.read()

js = execjs.compile(js_code)

headers = {
    'Accept': 'application/json, text/plain, */*',
    'Accept-Language': 'zh-CN,zh;q=0.9',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Origin': 'https://fanyi.youdao.com',
    'Pragma': 'no-cache',
    'Referer': 'https://fanyi.youdao.com/',
    'Sec-Fetch-Dest': 'empty',
    'Sec-Fetch-Mode': 'cors',
    'Sec-Fetch-Site': 'same-site',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36',
    'sec-ch-ua': '"Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Windows"',
}
name = '英语'
t = str(int(time.time() * 1000))
print(t)
data = {
    'i': name,
    'from': 'auto',
    'to': '',
    'domain': '0',
    'dictResult': 'true',
    'keyid': 'webfanyi',
    'sign': js.call('encryptSign', t),
    'client': 'fanyideskweb',
    'product': 'webfanyi',
    'appVersion': '1.0.0',
    'vendor': 'web',
    'pointParam': 'client,mysticTime,product',
    'mysticTime': t,
    'keyfrom': 'fanyi.web',
    'mid': '1',
    'screen': '1',
    'model': '1',
    'network': 'wifi',
    'abtest': '0',
    'yduuid': 'abcdefg',
}
# 要加上cookies
response = requests.post('https://dict.youdao.com/webtranslate', headers=headers, data=data)


print('解密:', js.call('maindata', str(response.text)))

结尾

到这就已经结束了,欢迎大家的点赞关注。 2023.10.3 23:50

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1060431.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

10月4日作业

server #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//实例化一个服务器server new QTcpServer(this);connect(server, &QTcpServer::newConnection, …

CANoe.Diva生成测试用例

Diva目录 一、CANoe.Diva打开CDD文件二、导入CDD文件三、ECU Information四、时间参数设置五、选择是否测试功能寻址六、勾选需要测试服务项七、生成测试用例 一、CANoe.Diva打开CDD文件 CANoe.Diva可以通过导入cdd或odx文件,自动生成全面的测试用例。再在CANoe中导…

Android学习之路(20) 进程间通信

IPC IPC为 (Inter-Process Communication) 缩写,称为进程间通信或跨进程通信,指两个进程间进行数据交换的过程。安卓中主要采用 Binder 进行进程间通信,当然也支持其他 IPC 方式,如:管道,Socket&#xff0…

9.3 链表从指定节点插入新节点

一、从指定节点后方插入 插入逻辑如图&#xff1a; 插入前&#xff1a;A指向B&#xff0c;B指向C 插入后&#xff1a;B为插入点&#xff0c;当要插入D时就要让B指向D&#xff0c;D再指向C&#xff08;插入前B的指向&#xff09; #include <stdio.h>struct Test {int d…

C/C++字符函数和字符串函数详解————内存函数详解与模拟

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 C语言刷题 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力&#xff0c;一起奔赴大厂。 目录 1.前言 2 .memcpy函数 3.memmove函…

mysql双主+双从集群连接模式

架构图&#xff1a; 详细内容参考&#xff1a; 结果展示&#xff1a; 178.119.30.14(主) 178.119.30.15(主) 178.119.30.16(从) 178.119.30.17(从)

【软件设计师-中级——刷题记录6(纯干货)】

目录 管道——过滤器软件体系结构风格优点&#xff1a;计算机英语重点词汇&#xff1a;单元测试主要检查模块的以下5个特征&#xff1a;数据库之并发控制中的事务&#xff1a;并发产生的问题解决方案:封锁协议原型化开发方法&#xff1a; 每日一言&#xff1a;持续更新中... 个…

N. Number Reduction

Problem - 1765N - Codeforces 发现如果是无前导0最小数那么在保证删除k个数时第1位是最小的&#xff0c;第二位一定是相对最小的&#xff0c;且答案第一位和第二位在原位置的间隔是小于等于还可以删除的位数的。 因此&#xff0c;对于原数字长度位n&#xff0c;要删除k&#…

Spring:通过@Lazy解决构造方法形式的循环依赖问题

一、定义2个循环依赖的类 package cn.edu.tju.domain2;import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component;Component public class A {private final B b;public B getB() {return b;}Lazypublic A(B b){this.b b;//Sy…

python获取时间戳

使用 datetime 库获取时间。 获取当前时间&#xff1a; import datetime print(datetime.datetime.now()) . 后面的是微秒&#xff0c;也是一个时间单位&#xff0c;1秒1000000微秒。 转为时间戳&#xff1a; import datetimedate datetime.datetime.now() timestamp date…

计算机系统中丢失MSVCR100.dll的解决方法,三个方法快速搞定

msvcr100.dll 是一个非常重要的系统文件&#xff0c;它属于 Microsoft Visual C Redistributable 的一个组件。这个文件包含了用于 C 编程的一些运行时库&#xff0c;对于许多软件和游戏的运行至关重要。如果您的电脑提示找不到 msvcr100.dll 文件&#xff0c;您可能会遇到一些…

STM32驱动步进电机

前言 &#xff08;1&#xff09;本章介绍用stm32驱动42步进电机&#xff0c;将介绍需要准备的硬件器材、所需芯片资源以及怎么编程及源代码等等。 &#xff08;2&#xff09;实验效果&#xff1a;按下按键&#xff0c;步进电机顺时针或逆时针旋转90度。 &#xff08;3&#xff…

浏览器从输入URL到展示的流程

文章目录 1. URL输入2. DNS解析3. 建立TCP连接4. 发送http或者https请求5. 服务器端响应请求6. 浏览器解析渲染页面7. 断开TCP连接 1. URL输入 输入URL后&#xff0c;浏览器会对URL进行以下的判断 是否合法如果合法&#xff0c;则判断URL是否完整&#xff0c;如果不完整&…

【C 语言进阶(12)】动态内存管理笔试题

文章目录 题目 1题目 2题目 3题目 4 题目 1 运行 Test 函数后的结果是什么&#xff1f; void GetMemory(char* p) {p (char*)malloc(100); }void Test(void) {char* str NULL;GetMemory(str);strcpy(str, "hello world");printf(str); }代码结果 程序崩溃。 代…

openGauss学习笔记-89 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用查询原生编译

文章目录 openGauss学习笔记-89 openGauss 数据库管理-内存优化表MOT管理-内存表特性-使用MOT-MOT使用查询原生编译89.1 查询编译&#xff1a;PREPARE语句89.2 运行命令89.3 轻量执行支持的查询89.4 轻量执行不支持的查询89.5 JIT存储过程89.6 MOT JIT诊断89.6.1 mot_jit_detai…

MATLAB 函数签名器

文章目录 MATLAB 函数签名器注释规范模板参数类型 kind数据格式 type选项的支持 使用可执行程序封装为m函数程序输出 编译待办事项推荐阅读附录 MATLAB 函数签名器 MATLAB 函数签名器 (FUNCSIGN) &#xff0c;在规范注释格式的基础上为函数文件或类文件自动生成函数签名&#…

c++ 基础知识(一)

文章目录 1. C关键字 2. 命名空间 3. C输入&输出 4. 缺省参数 文章内容 1. C关键字(C98) C总计63个关键字&#xff0c;C语言32个关键字 ps&#xff1a;下面我们只是看一下C有多少关键字&#xff0c;不对关键字进行具体的讲解。后面我学了以后再细讲。 2. 命名空间 …

简单查找重复文本文件

声明这是最初 我的提问给个文本分类清单input查找文件夹下 .py .txt .excel .word 一模一样的文本不是找文件名 找相同格式下的文件文本是否一样 文件单独复制到文件夹下两个文件全部复制到文件夹下 print 打印相同文本文件的名字 比如查找到了3.py与4.5.是.py文件中的文本文件…

Java基础API---euqals 小知识

导入&#xff1a; 大家有没有遇到自定义的类&#xff0c;无法用equals方法比较成员属性呀&#xff1f;那是因为需要重写equals方法 重写原理这里偷个懒&#xff0c;idea中 altinsert 快捷键&#xff0c;快速实现重写equals噢&#xff01; Student类&#xff1a; package ob…

【C++】基础入门

万字复习C基础入门语法&#xff0c;适合学过C的朋友用来复习查阅&#xff0c;可能不太适合0基础的朋友。 一.c初识 (1) 第一个c程序 最简单的格式&#xff1a; // 导入头文件 #include<iostream> // 简化对命名空间std下函数和对象的使用 using namespace std; // …