什么?你居然还不会分析网站加密算法?某翻译网站JS算法还原实战
站点:aHR0cHM6Ly9mYW55aS55b3VkYW8uY29tLw==## 1.分析
首先输入内容后会立马自动返回翻译结果,观察`network`发现发送了一个`XHR`请求。
经过多次发送对比后发现,`salt`、`lts`、`sign`为每次会变化,`salt`、`lts`参数应该是时间戳,但是`salt`比`lts`多处了一位。
## 2. 跟进
通过堆栈跟进后最终来到`fanyi.min.js`的`8392`行发现加密函数。
`t`参数发现是为`n.md5(navigator.appVersion)`也就是请求包中的`lts`参数,使用的是浏览器版本号加密。
`salt`盐值为:`r + parseInt(10 * Math.random(), 10)` ,`r`为13位时间戳,也就是时间戳加上一位十进制的随机数。
`sign`需要用到参数`e`和`i`,其中`i`是已经知道的,`e`就是用户需要翻译的内容。
不会跟代码的请点击[ 视频实战](https://ke.qq.com/course/5814082#term_id=106024084) ,第`3`个视频就是这个案例!
## 3. 还原
通过使用其他MD5进行加密后和`n.md5(navigator.appVersion)`加密结果对比,发现为原生加密算法,那么直接使用Python进行写代码。
```python
import hashlib
import random
import time
import requests
import execjs
def get_params(userTranslate):
agent = '5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
bv=hashlib.md5(agent.encode('utf-8')).hexdigest()
ts = int(round(time.time() * 1000))
salt = ts + random.randint(0,9)
sign =hashlib.md5(str("fanyideskweb" + userTranslate +str(salt) + "Ygy_4c=r#e#4EX^NUGUc5").encode('utf-8')).hexdigest()
params={
"i": userTranslate,
"from": "AUTO",
"to": 'AUTO',
"smartresult": 'dict',
"client": 'fanyideskweb',
'salt': salt,
'sign': sign,
'lts':ts,
'bv': bv,
'doctype': 'json',
'version': 2.1,
'keyfrom': 'fanyi.web',
'action': 'FY_BY_REALTlME'
}
return params
HEADERS= {
'Cookie': 'OUTFOX_SEARCH_USER_ID=1010604068@10.105.137.202; OUTFOX_SEARCH_USER_ID_NCOO=82578608.17978993; ___rl__test__cookies=1661492454526',
'Origin': 'https://fanyi.youdao.com',
'Pragma': 'no-cache',
'Referer': 'https://fanyi.youdao.com/',
'Sec-Fetch-Dest': 'empty',
'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest',
'sec-ch-ua': '"Chromium";v="104", " Not A;Brand";v="99", "Google Chrome";v="104"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': "macOS",
}
response = requests.post("https://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule",data=get_params("hello"),headers=HEADERS)
print(response.json()['smartResult']['entries'])
```
到这好像有太没意思了.... 那么干脆把网站原生JS算法扣下来了。
```python
# 使用网站原生的md5加密
import execjs
x = execjs.compile('''
var n = function(e, t) {
return e << t | e >>> 32 - t
}
, r = function(e, t) {
var n, r, i, o, a;
return i = 2147483648 & e,
o = 2147483648 & t,
n = 1073741824 & e,
r = 1073741824 & t,
a = (1073741823 & e) + (1073741823 & t),
n & r ? 2147483648 ^ a ^ i ^ o : n | r ? 1073741824 & a ? 3221225472 ^ a ^ i ^ o : 1073741824 ^ a ^ i ^ o : a ^ i ^ o
}
, i = function(e, t, n) {
return e & t | ~e & n
}
, o = function(e, t, n) {
return e & n | t & ~n
}
, a = function(e, t, n) {
return e ^ t ^ n
}
, s = function(e, t, n) {
return t ^ (e | ~n)
}
, l = function(e, t, o, a, s, l, c) {
return e = r(e, r(r(i(t, o, a), s), c)),
r(n(e, l), t)
}
, c = function(e, t, i, a, s, l, c) {
return e = r(e, r(r(o(t, i, a), s), c)),
r(n(e, l), t)
}
, u = function(e, t, i, o, s, l, c) {
return e = r(e, r(r(a(t, i, o), s), c)),
r(n(e, l), t)
}
, d = function(e, t, i, o, a, l, c) {
return e = r(e, r(r(s(t, i, o), a), c)),
r(n(e, l), t)
}
, f = function(e) {
for (var t, n = e.length, r = n + 8, i = 16 * ((r - r % 64) / 64 + 1), o = Array(i - 1), a = 0, s = 0; s < n; )
a = s % 4 * 8,
o = o | e.charCodeAt(s) << a,
s++;
return t = (s - s % 4) / 4,
a = s % 4 * 8,
o = o | 128 << a,
o = n << 3,
o = n >>> 29,
o
}
, p = function(e) {
var t, n = "", r = "";
for (t = 0; t <= 3; t++)
n += (r = "0" + (e >>> 8 * t & 255).toString(16)).substr(r.length - 2, 2);
return n
}
, h = function(e) {
for (var t = "", n = 0; n < e.length; n++) {
var r = e.charCodeAt(n);
if (r < 128)
t += String.fromCharCode(r);
else if (r > 127 && r < 2048)
t += String.fromCharCode(r >> 6 | 192),
t += String.fromCharCode(63 & r | 128);
else if (r >= 55296 && r <= 56319) {
if (n + 1 < e.length) {
var i = e.charCodeAt(n + 1);
if (i >= 56320 && i <= 57343) {
var o = 1024 * (r - 55296) + (i - 56320) + 65536;
t += String.fromCharCode(240 | o >> 18 & 7),
t += String.fromCharCode(128 | o >> 12 & 63),
t += String.fromCharCode(128 | o >> 6 & 63),
t += String.fromCharCode(128 | 63 & o),
n++
}
}
} else
t += String.fromCharCode(r >> 12 | 224),
t += String.fromCharCode(r >> 6 & 63 | 128),
t += String.fromCharCode(63 & r | 128)
}
return t
};
md5=function(e) {
var t, n, i, o, a, s, m, g, v, y = Array();
for (e = e,
y = f(e),
s = 1732584193,
m = 4023233417,
g = 2562383102,
v = 271733878,
t = 0; t < y.length; t += 16)
n = s,
i = m,
o = g,
a = v,
s = l(s, m, g, v, y, 7, 3614090360),
v = l(v, s, m, g, y, 12, 3905402710),
g = l(g, v, s, m, y, 17, 606105819),
m = l(m, g, v, s, y, 22, 3250441966),
s = l(s, m, g, v, y, 7, 4118548399),
v = l(v, s, m, g, y, 12, 1200080426),
g = l(g, v, s, m, y, 17, 2821735955),
m = l(m, g, v, s, y, 22, 4249261313),
s = l(s, m, g, v, y, 7, 1770035416),
v = l(v, s, m, g, y, 12, 2336552879),
g = l(g, v, s, m, y, 17, 4294925233),
m = l(m, g, v, s, y, 22, 2304563134),
s = l(s, m, g, v, y, 7, 1804603682),
v = l(v, s, m, g, y, 12, 4254626195),
g = l(g, v, s, m, y, 17, 2792965006),
m = l(m, g, v, s, y, 22, 1236535329),
s = c(s, m, g, v, y, 5, 4129170786),
v = c(v, s, m, g, y, 9, 3225465664),
g = c(g, v, s, m, y, 14, 643717713),
m = c(m, g, v, s, y, 20, 3921069994),
s = c(s, m, g, v, y, 5, 3593408605),
v = c(v, s, m, g, y, 9, 38016083),
g = c(g, v, s, m, y, 14, 3634488961),
m = c(m, g, v, s, y, 20, 3889429448),
s = c(s, m, g, v, y, 5, 568446438),
v = c(v, s, m, g, y, 9, 3275163606),
g = c(g, v, s, m, y, 14, 4107603335),
m = c(m, g, v, s, y, 20, 1163531501),
s = c(s, m, g, v, y, 5, 2850285829),
v = c(v, s, m, g, y, 9, 4243563512),
g = c(g, v, s, m, y, 14, 1735328473),
m = c(m, g, v, s, y, 20, 2368359562),
s = u(s, m, g, v, y, 4, 4294588738),
v = u(v, s, m, g, y, 11, 2272392833),
g = u(g, v, s, m, y, 16, 1839030562),
m = u(m, g, v, s, y, 23, 4259657740),
s = u(s, m, g, v, y, 4, 2763975236),
v = u(v, s, m, g, y, 11, 1272893353),
g = u(g, v, s, m, y, 16, 4139469664),
m = u(m, g, v, s, y, 23, 3200236656),
s = u(s, m, g, v, y, 4, 681279174),
v = u(v, s, m, g, y, 11, 3936430074),
g = u(g, v, s, m, y, 16, 3572445317),
m = u(m, g, v, s, y, 23, 76029189),
s = u(s, m, g, v, y, 4, 3654602809),
v = u(v, s, m, g, y, 11, 3873151461),
g = u(g, v, s, m, y, 16, 530742520),
m = u(m, g, v, s, y, 23, 3299628645),
s = d(s, m, g, v, y, 6, 4096336452),
v = d(v, s, m, g, y, 10, 1126891415),
g = d(g, v, s, m, y, 15, 2878612391),
m = d(m, g, v, s, y, 21, 4237533241),
s = d(s, m, g, v, y, 6, 1700485571),
v = d(v, s, m, g, y, 10, 2399980690),
g = d(g, v, s, m, y, 15, 4293915773),
m = d(m, g, v, s, y, 21, 2240044497),
s = d(s, m, g, v, y, 6, 1873313359),
v = d(v, s, m, g, y, 10, 4264355552),
g = d(g, v, s, m, y, 15, 2734768916),
m = d(m, g, v, s, y, 21, 1309151649),
s = d(s, m, g, v, y, 6, 4149444226),
v = d(v, s, m, g, y, 10, 3174756917),
g = d(g, v, s, m, y, 15, 718787259),
m = d(m, g, v, s, y, 21, 3951481745),
s = r(s, n),
m = r(m, i),
g = r(g, o),
v = r(v, a);
return (p(s) + p(m) + p(g) + p(v)).toLowerCase()
}
''')
agent = '5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
print(x.call('md5',agent))
```
Ok ,使用execjs库执行扣下来的代码也是没问题的,收工👋 帖子有价值值得学习,百度的也要sign了,这个站点有个不需要key的 aHR0cDovL2ZhbnlpLnlvdWRhby5jb20vdHJhbnNsYXRlPyZkb2N0eXBlPWpzb24mdHlwZT1BVVRPJmk9aGVsbG8= 最后的参数是需要翻译的 忆白学渣 发表于 2022-9-2 17:40
546w5Zyo5aSn5a626K+06K+d6YO95b6X5Yqg5a+G5ZCX77yfCiA=
77yI5bCP5aOw6YC86YC877yJNkwrWjVMaXE1YnFVNksrbDVZK3I0b0NjNTd5VzU2Q0I0b0NkNXB1MDVZZUc1Nkd1NVpDbg== 底部多了一个图片没插入? 真的不会,感谢分享最近老是看到有H大冒泡啊 546w5Zyo5aSn5a626K+06K+d6YO95b6X5Yqg5a+G5ZCX77yfCiA= 代码拿走了,谢谢分享 谢谢分享,谢谢分享!
孤狼微博 发表于 2022-9-2 17:27
帖子有价值值得学习,百度的也要sign了,这个站点有个不需要key的 aHR0cDovL2ZhbnlpLnlvdWRhby5jb20vdHJhbnNs ...
{:1_921:}代码又精简不少! 感谢大佬分享 感谢感谢感谢感谢