文章目录
- 前文
- 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