news 2026/7/20 13:13:13

某当网登录滑块【协议+OCR】

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
某当网登录滑块【协议+OCR】

一、观察接口特征

  1. 获取密钥接口。第一个接口getRankey:
  • 请求载荷分析:
  • 响应值分析:

    2.获取滑块图片接口。 跳过isShowSlide接口直接看getSlidingVerifyCode接口,因为返回值无重要信息:
  • 请求载荷里面含requestId,大概率就是第一次分析的接口中返回回来的
  • 响应值:很明显能看见返回了很多重要信息,可见这里是验证码的核心接口,因为含有背景和滑块图的地址。
  1. 验证滑块接口。滑动滑块,分析滑块验证接口checkSlidingVerifyCode:
  • 请求载荷:
  • 响应载荷对比(失败和成功):

  1. 登录验证接口。accountLogin:

二、定位每个接口的sign值生成位置并分析其加密逻辑

  1. 直接全局搜索sign
  2. 直接点进去断点观察
  3. 接着对r进行了一次编码,但得到的新r没有变化,可以不用管
  4. 对r进行了标准的MD5加密
  5. 将md5加密后的字符串传入Y函数,断点跟进Y函数内部可以看见是一个AES对称加密算法,上帝视角后面的sign值都走的这个逻辑,因为后面都是要挨个断点调试的,所以就能看出来。所以我们直接将这个AES加密过程拿到本地js文件中保存下来,方便后续纯nodejs调用。

三、定位checkSlidingVerifyCode接口中的point_json

  1. 还是直接全局搜索point_json
  2. 定位到point_json生成位置,就是将滑块到缺口的横纵坐标对象和getSlidingVerifyCode接口返回的encryptKey值当参数传给Y函数进行加密。
  3. 注意x的值,浏览渲染比例是350,所以它除的是350,而我们拿到的图片比例要除以408。

四、理清逆向思路

我们发现:

  1. 关键有4个接口:
  • getRankey接口获取密钥 rankey值 和 requestId值
  • getSlidingVerifyCode接口获取滑块、背景图片,encryptKey、token和y值
  • checkSlidingVerifyCode接口获取 checkCode 值
  • accountLogin接口做最后的登录处理
  1. 每个接口请求载荷中:
  • 均需要时间戳模拟,直接上time库
  • permanent_id均从cookie中直接取值
  • 后3个接口中的requestId值均从第一个接口的返回值中拿
  • 每个接口的sign值都是将该接口的请求参数拼接后经过md5加密,再和rankey值一起(除getRankey接口传空字符串)传入Y函数,也就是AES对称加密函数加密得到的值
  • checkSlidingVerifyCode接口中的point_json值就是将明文密码和’qrcode_p@ssw0rdK’传入Y函数的返回值

五、代码展示

importrequests,time,hashlib,execjs,jsonfromddddocrimportDdddOcrclassSpider():def__init__(self):self.cookies="自己复制cookie"self.headers="自己的header"self.ocr=DdddOcr()withopen("./main.js","r",encoding="utf-8")asf:self.ctx=execjs.compile(f.read())defget_rankey_requestId(self):url="https://login.dangdang.com/api/customer/loginapi/getRankey"ts=int(time.time()*1000)data={"t":f'{ts}',"ct":"pc","permanent_id":self.cookies["__permanent_id"],"requestId":"","sign":"dxuL7I267hpFvpCnlF0IvrEpJz3GO2NkHMGo2A5LdukezDpDPhqo+7lqMpklKBlS"}# 检测了ct开头params_data=f"ct=pc&permanent_id={data['permanent_id']}&t={ts}"sign=self.ctx.call("aes",hashlib.md5(params_data.encode()).hexdigest(),'')data["sign"]=sign res=requests.post(url,headers=self.headers,cookies=self.cookies,data=data)print(res.json())returnres.json()["rankey"],res.json()["requestId"]defget_VerifyImage(self,rankey,requestId):url="https://login.dangdang.com/api/customer/loginapi/getSlidingVerifyCode"ts=int(time.time()*1000)data={"t":f'{ts}',"ct":"pc","permanent_id":self.cookies["__permanent_id"],"requestId":requestId,"situation":"login",}params_data=f"ct=pc&permanent_id={data['permanent_id']}&requestId={requestId}&situation=login&t={ts}"sign=self.ctx.call("aes",hashlib.md5(params_data.encode()).hexdigest(),rankey)data["sign"]=sign response=requests.post(url,headers=self.headers,cookies=self.cookies,data=data).json()slide_url=response['data']['slideImg']bg_url=response['data']['bgImg']encryptKey=response['data']['encryptKey']y=response['data']['y']token=response['data']['token']print(response)returnslide_url,bg_url,encryptKey,y,tokendefget_move_x(self,slide_url,bg_url):slide_bytes=requests.get(slide_url).content bg_bytes=requests.get(bg_url).content res=self.ocr.slide_match(slide_bytes,bg_bytes,simple_target=True)ifres:gap_x=res['target'][0]print(f'缺口x坐标:{gap_x}')returngap_xelse:print("识别失败")defcheckSlidingVerifyCode(self,x,y,encryptKey,requestId,token,rankey):url="https://login.dangdang.com/api/customer/loginapi/checkSlidingVerifyCode"ts=int(time.time()*1000)data={"t":f'{ts}',"ct":"pc","permanent_id":self.cookies["__permanent_id"],"requestId":requestId,"situation":"login","verifyToken":token,"slide_cost_time":"108","need_new_verifydata":"0","sign":"uPjqm2GFKsc2NxfEE5oZreAFgvmlZB9RTsNNgUXJAZ6TUiQS9ClQ8w02BLTquYMj"}t={"x":x/408,"y":y}point_json=self.ctx.call("aes",json.dumps(t,separators=(',',':')),encryptKey)data['point_json']=point_json params_data=f"ct=pc&need_new_verifydata=0&permanent_id={data['permanent_id']}&point_json={data['point_json']}&requestId={requestId}&situation=login&slide_cost_time=108&t={ts}&verifyToken={token}"sign=self.ctx.call("aes",hashlib.md5(params_data.encode()).hexdigest(),rankey)data['sign']=sign response=requests.post(url,headers=self.headers,cookies=self.cookies,data=data)print(response.json())returnresponse.json()["data"]['checkCode']deflogin(self,requestId,token,checkCode,rankey):url="https://login.dangdang.com/api/customer/loginapi/accountLogin"ts=int(time.time()*1000)username='123456789'psw='123456'password=self.ctx.call("aes",psw,"qrcode_p@ssw0rdK")data={"t":f"{ts}","ct":"pc","permanent_id":self.cookies["__permanent_id"],"requestId":requestId,"username":username,"password":password,"autokey":"off","token":token,"check_code":checkCode,"check_code_type":"1",}params_data=f"autokey=off&check_code={checkCode}&check_code_type=1&ct=pc&password={data['password']}&permanent_id={data['permanent_id']}&requestId={requestId}&t={ts}&token={token}&username={username}"sign=self.ctx.call('aes',hashlib.md5(params_data.encode()).hexdigest(),rankey)data['sign']=sign response=requests.post(url,headers=self.headers,cookies=self.cookies,data=data)print(response.json())if__name__=='__main__':s=Spider()# 第一个接口拿密钥rankey,requestId=s.get_rankey_requestId()# 第二个接口拿图片地址,encryptKey,y和tokenslide_url,bg_url,encryptKey,y,token=s.get_VerifyImage(rankey,requestId)# ocr识别 x 距离x=s.get_move_x(slide_url,bg_url)# 第三个接口获取checkCode值checkCode=s.checkSlidingVerifyCode(x,y,encryptKey,requestId,token,rankey)# 第4个接口直接登录s.login(requestId,token,checkCode,rankey)

结语:本文仅供学习使用,如有侵权,立即删除。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/20 13:12:10

终极指南:OpCore-Simplify智能OpenCore EFI配置工具全解析

终极指南:OpCore-Simplify智能OpenCore EFI配置工具全解析 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 你是否曾为Hackintosh的复杂配置…

作者头像 李华
网站建设 2026/7/20 13:12:06

剪映AI数字人爆火背后的5个隐藏技巧:90%创作者还不知道的提效秘钥

更多请点击: https://codechina.net 第一章:剪映AI数字人爆火现象与底层技术解构 剪映AI数字人功能自2023年上线以来,日均生成视频超千万条,用户留存率较传统模板编辑提升47%,成为短视频内容工业化生产的关键拐点。其…

作者头像 李华
网站建设 2026/7/20 13:12:05

TI AM263P ePWM事件触发与数字比较模块实战解析

1. 项目概述与核心价值在搞电机控制或者数字电源的兄弟,肯定都遇到过这样的场景:你想在PWM波形的某个精确时刻(比如计数器等于比较值的那一刻)去触发ADC采样,或者当某个外部故障信号(比如过流比较器输出&am…

作者头像 李华
网站建设 2026/7/20 13:11:57

深入解析PRU-ICSS:工业实时协处理器的架构、内存映射与EGPIO实战

1. PRU-ICSS架构概览与核心价值在工业自动化、电机驱动和高速通信接口的开发中,我们常常会遇到一个核心矛盾:主处理器(如Arm Cortex-A/M系列)需要处理复杂的操作系统、网络协议和应用逻辑,而一些对时序要求极其苛刻的任…

作者头像 李华
网站建设 2026/7/20 13:10:40

AI搜索可见度优化:从技术原理到工程实践

随着生成式AI搜索引擎(如百度ERNIE、字节豆包、阿里通义千问)的普及,品牌和内容的AI可见度(AI Visibility)已成为数字营销的新课题。本文从技术角度解析AI搜索如何引用内容,并给出可落地的优化方案。 AI搜…

作者头像 李华