关注微信公众号:K哥爬虫,QQ交换群:808574309,继续分享爬虫进阶、JS/安卓逆向等技术干货!

申明

本文章中所有内容仅供学习交换,抓包内容、敏感网址、数据接口均已做脱敏解决,严禁用于商业用途和非法用处,否则由此产生的所有结果均与作者无关,若有侵权,请分割我立刻删除!

逆向指标

  • 指标:cnki 学术翻译 AES 加密
  • 主页:aHR0cHM6Ly9kaWN0LmNua2kubmV0L2luZGV4
  • 接口:aHR0cHM6Ly9kaWN0LmNua2kubmV0L2Z5enMtZnJvbnQtYXBpL3RyYW5zbGF0ZS9saXRlcmFsdHJhbnNsYXRpb24=
  • 逆向参数:Request Payload:words: "kufhG_UJw_k3Sfr3j0BLAA=="

逆向过程

本期逆向素材来源于K哥爬虫交换群里某位群友的求助,指标是 cnki 学术翻译,粉丝想实现两个性能:1、冲破英文1000个字符的限度;2、逆向加密过程。

来到翻译首页,抓包定位到翻译接口,能够看到 Request Payload 里,待翻译文本会被加密解决,如下图所示:

这里如果间接搜寻关键字 words,会发现后果十分多,不太好找,留神到 Payload 参数里还有个 translateType,那么就能够间接搜寻 translateType,因为这两个参数个别都是挨着的,当然也能够应用 XHR 断点的形式来找,只不过麻烦一些,搜寻后果都在 app.9fb42bb0.js 里,留神到最初一个后果里有 encrypto,加密的意思,基本上就是加密的中央了:

控制台打印一下 (0, h.encrypto)(this.inputWord),正是加密后果:

持续跟进一下 h.encrypto,很显著的 AES 加密,n = "4e87183cfd3a45fe",n 就是 key,模式 ECB,填充 Pkcs7,最初做了一些字符串的替换解决,如下图所示:

晓得了加密算法,key 等要害参数,那么间接援用 crypto-js 模块来实现就 OK 了,JavaScript 代码如下:

// 援用 crypto-js 加密模块var CryptoJS = require('crypto-js')function s(t) {    var n = "4e87183cfd3a45fe"    var e = {        mode: CryptoJS.mode.ECB,        padding: CryptoJS.pad.Pkcs7    }      , i = CryptoJS.enc.Utf8.parse(n)      , s = CryptoJS.AES.encrypt(t, i, e)      , r = s.toString().replace(/\//g, "_");    return r = r.replace(/\+/g, "-"),    r}console.log(s("测试"))// kufhG_UJw_k3Sfr3j0BLAA==

应用 Python 翻译的一个小 demo:

# ==================================# --*-- coding: utf-8 --*--# @Time    : 2021-11-05# @Author  : 微信公众号:K哥爬虫# @FileName: cnki.py# @Software: PyCharm# ==================================import execjsimport requeststoken_url = "https://dict.cnki.net/fyzs-front-api/getToken"translation_api = "https://dict.cnki.net/fyzs-front-api/translate/literaltranslation"UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36"session = requests.session()def get_token():    headers = {"User-Agent": UA}    response = session.get(url=token_url, headers=headers).json()    token = response["data"]    return tokendef get_encrypted_word(word):    with open('cnki_encrypt.js', 'r', encoding='utf-8') as f:        cnki_js = f.read()    encrypted_word = execjs.compile(cnki_js).call('s', word)    return encrypted_worddef get_translation_result(encrypted_word, token):    payload = {        "translateType": None,        "words": encrypted_word    }    headers = {        "Token": token,        "User-Agent": UA    }    response = session.post(url=translation_api, headers=headers, json=payload).json()    result = response["data"]["mResult"]    return resultdef main():    word = input("请输出待翻译字符串: ")    token = get_token()    encrypted_word = get_encrypted_word(word)    result = get_translation_result(encrypted_word, token)    print("翻译后果为: ", result)if __name__ == "__main__":    main()

粉丝还有一个问题就是字符数限度问题,看能不能冲破,实测英文限度1000字符,中文限度500字符,如下图所示:

这种限度其实大概率不仅仅是前端的限度,服务端应该也是有限度的,咱们能够携带超过500字符的中文去申请一下,后面的字符是“测试1”,最初三个字符是“测试2”,此时已超过了500个字符,咱们看到翻译后果里并没有呈现 Test 2,所以想要翻译很多字符串,只能将其宰割成几份来解决了。