A-A+

有dao翻译 sign 再分析

2025年01月27日 10:42 学习笔记 暂无评论 共2528字 (阅读97 views次)

【注意:此文章为博主原创文章!转载需注意,请带原文链接,至少也要是txt格式!】

其实网上关于有道翻译分析sign签名加密方法的分析文章已经铺天盖地了,但是只不过前段时间刚好无疑看到相关文章,但是没有写返回数据解密的逻辑,想着自己还是去看一下,然后详细写个文章。

分析post请求sign

首先通过浏览器的F12中,可以看到有一条https://dict.youdao.com/webtranslate/key这个地址的网络请求。这条请求中夹带着sign,同时这条请求返回了aesIvaesKeysecretKey这3个参数,基本不用问,看字面意思就很明确,是aes加密所需要的iv填充密钥、key加密密钥。具体如下图:

images

因为发现每次翻译前都会有这个url地址的请求,所以我们先根据这个url地址进行拦截。拦截含有/webtranslate/key的请求。然后我们看一下,程序会断点到哪里。这个时候就要注意了,一般拦截断点的地方大概率都不是加密的地方都需要向上一点点找。

images

首先看绿色的->->,然后从绿色的3跳到了绿色的圈内,然后再圈内看蓝色的->->

其实这样看整体思路就是比较清晰了。sign加密是在k(t)函数内完成的,因为是/webtranslate/key的请求,并不是翻译任何英文,所以参数t=undefined就是空,没有定义。

那现在看一下k函数里面的及S函数的加密逻辑吧。这里除了变量t为空之外,其他的基本都是固定的,只有a取了当前的时间。把它都赋值上再简单看一下代码逻辑:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function _(e) {
     //③注释:其实最终也就是取的md5值
    return i.createHash("md5").update(e.toString()).digest("hex")
}
function S(e, t) {
    //②然后对上面的参数取md5值
    return _(`client=${d}&mysticTime=${e}&product=${u}&key=${t}`)
}
function k(e, t) {
    const a = (new Date).getTime();
    return {
        sign: S(a, e),     //①注释:这里直接调用到了上面的函数,a就是当前的时间, e="asdjnjfenknafdfsdfsd" 
        client: d="fanyideskweb",
        product: u="webfanyi",
        appVersion: m="1.0.0",
        vendor: h="web",
        pointParam: p="client,mysticTime,product",
        mysticTime: a,
        keyfrom: g="fanyi.web",
        mid: b=1,
        screen: f=1,
        model: v=1,
        network: A="wifi",
        abtest: y=0,
        yduuid: t || "abcdefg"   //注释:因为t为空,所以这里肯定取值是"abcdefg"
    }
}

其实大致逻辑就很清晰了。不过这里有一个注意点就是

①当请求uri地址是/webtranslate/key这个时,注意这个函数k(e="asdjnjfenknafdfsdfsd" , t=undefined)所以是取"client=fanyideskweb&mysticTime=1737873042843&product=webfanyi&key=asdjnjfenknafdfsdfsd"的md5值。

②当请求uri地址是/webtranslate这个时,注意这个函数k(e="Vy4EQ1uwPkUoqvcP1nIu6WiAjxFeA3Y9"
, t=undefined)所以是取"client=fanyideskweb&mysticTime=1737873219314&product=webfanyi&key=Vy4EQ1uwPkUoqvcP1nIu6WiAjxFeA3Y9"的md5值。

 

至此整体逻辑就是,首先每次都请求/webtranslate/key这个接口,然后获取返回的aesIvaesKeysecretKey这3个参数,然后再通过secretKey去组合进行md5加密你要翻译的英文,然后变为sign,其他的值除了那个时间戳,都是固定的。

 

至此请求分析完毕,但是!!!大家看下图:

images

针对翻译的请求的返回数据是加密的,那么我们直接跟进这个请求的返回结果继续追踪一下。如下图:

images

其实到这里就已经明显的不能再明显了。只要再跟进da.A.decodeData(o, ha.A.state.text.decodeKey, ha.A.state.text.decodeIv) 这个函数就OK了。

ha.A.state.text.decodeKey = aesKey = "ydsecret://query/key/B*RGygVywfNBwpmBaZg*WT7SIOUP2T0C9WHMZN39j^DAdaZhAnxvGcCY6VYFwnHl"

ha.A.state.text.decodeIv = aesIv = "ydsecret://query/iv/C@lZe2YzHtZ2CYgaXKSVfsb7Y4QWHjITPPZ0nQp87fBeJ!Iv6v^6fvi2WN@bYpJ4"
这些都是刚刚通过/webtranslate/key这个接口获取到的数据,而刚刚接口o就是返回的密文,我们再跟进去查看一下。

images

当跟进来后就到了这里,注意仔细看图,O = (e, t, a) 分别就对应上面的传参。

这里做一个简单的解释l.alloc(16, T(t)) 这里的T()函数就是进行md5加密,如下图:

images

注意下方有一个base64,明显就是要针对返回值进行base64解码,但是返回值中有"-"、"_"明显不对,base64中没有这个字符,在这个地方我思考了很久没有明白为什么。通过找别人分析的文章发现有一个人说如下:

images

后来自己做了一个详细的跟进,发现了关键点,如下图:

images

然后把整段代码喂给了gpt,最终gpt答复如下:

images

所以就简单了,后续遇到类似base64的乱码别放弃,追踪到指定解密位置,直接让gpt去一点点看,给你答案就OK了。那至此就非常非常简单了。

 

最终成品代码参考:https://www.cnblogs.com/hp-mzx/p/17684788.html

布施恩德可便相知重

微信扫一扫打赏

支付宝扫一扫打赏

×

给我留言