news 2026/6/4 20:35:00

Python 爬虫反爬突破:Cookie 加密生成算法逆向还原登录凭证

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python 爬虫反爬突破:Cookie 加密生成算法逆向还原登录凭证

前言

现代大中型互联网平台的用户登录环节已摒弃明文 Cookie 下发模式,多数后端依托自定义哈希、对称 / 非对称加密、时间戳加盐、动态密钥衍生等逻辑生成加密 Cookie 与登录凭证,常规抓包复制 Cookie、固定账号密码表单提交的爬虫方案会在短周期内失效,平台通过校验 Cookie 加密签名、时效字段完成爬虫访问拦截。针对加密 Cookie 逆向还原,可通过 JS 源码剥离加密逻辑、还原密钥与盐值、复刻客户端加密算法,由爬虫程序自主生成合法登录 Cookie,摆脱手动获取登录凭证的依赖,实现全自动持久化账号登录采集。 本文所需依赖库官方访问链接统一置于开篇,便于开发阶段查阅文档与安装配置:

  1. requests HTTP 请求库
  2. pycryptodome 加解密工具库
  3. execjs JS 引擎调用库
  4. hashlib Python 内置哈希库
  5. json 内置序列化库

全文从 Cookie 加密常见实现分类、前端 JS 逆向步骤、三种主流加密算法 Python 复刻、动态凭证生成实战、异常校验绕过、登录态持久化存储六大板块展开,搭配全量可运行工程代码,覆盖 MD5 加盐、AES 对称加密、RSA 非对称加密三类登录 Cookie 主流加密场景,落地爬虫全自动生成合法登录凭证的工程方案。

一、登录 Cookie 加密分类与反爬校验原理

1.1 平台登录 Cookie 主流加密类型划分

从前端逆向落地角度,网站登录凭证加密分为哈希加盐、对称加密、非对称加密三类,各类加密特征与应用场景整理如下表:

表格

加密类型核心实现特征Cookie 字段特征平台使用场景
加盐哈希加密基于 MD5/SHA1/SHA256 + 固定 / 动态盐值拼接摘要sign、token 字段为固定长度十六进制字符串中小型资讯、电商后台简易登录校验
AES 对称加密固定密钥 + 偏移量,明文账号信息加密生成密文密文长度不固定,含大小写字母与数字混合串中大型会员系统、移动端 H5 登录鉴权
RSA 非对称加密前端公钥加密关键参数,后端私钥解密校验密文字符长度偏大,无固定规律银行、票务、大型电商核心账号登录

1.2 加密 Cookie 反爬拦截底层逻辑

  1. 客户端登录请求携带账号、密码、时间戳、随机数,经前端加密生成签名字段;
  2. 后端使用同源加密规则与密钥复算签名,对比请求携带的 sign 值,不一致直接返回登录失败;
  3. 登录成功下发加密 Cookie,Cookie 内嵌时效戳、设备标识加密字段,每次接口请求后端二次解密校验有效性;
  4. 爬虫直接复用过期 Cookie、手动篡改 Cookie 参数,会触发会话失效、IP 风控拦截。

1.3 逆向还原 Cookie 核心思路

  1. 定位页面登录相关 JS 文件,剥离加密函数、密钥、固定盐值;
  2. 区分加密类型,使用 Python 复刻同等加密逻辑,保证输出密文与浏览器 JS 运算结果完全一致;
  3. 爬虫自主组装明文参数,通过自研加密函数生成合法签名,提交登录接口获取新鲜登录 Cookie;
  4. 缓存有效 Cookie,临近过期自动重新执行加密登录,实现全自动化凭证轮换。

二、项目环境与依赖安装

2.1 运行环境基准配置

Python3.8 及以上,Node.js 环境(execjs 运行原生 JS 代码必备,用于临时调试 JS 加密逻辑),Windows/Linux 全平台兼容。

2.2 第三方依赖一键安装指令

bash

运行

pip install requests pycryptodome execjs

2.3 依赖有效性校验代码

python

运行

import requests import execjs from Crypto.Cipher import AES, PKCS1_OAEP print("加解密相关依赖加载正常")

三、场景一:MD5 加盐哈希加密 Cookie 逆向复刻

3.1 加密原理说明

平台前端将账号+密码+时间戳+固定盐值secret_key拼接为原始明文,经 MD5 哈希运算生成 sign 签名字段,随登录表单一并提交,后端使用相同盐值复算 MD5 完成校验,登录成功返回携带加密 sign 的会话 Cookie。盐值硬编码在前端 JS 源码内,逆向目标即为提取 secret_key 与字段拼接顺序。

3.2 JS 源码逆向提取示例(模拟前端加密代码)

javascript

运行

// 从网站js文件剥离的原始加密逻辑 var secret = "k9s20df37gglp0x"; //逆向得到固定盐值 function getSign(username,pwd,ts){ var raw = username + pwd + ts + secret; return md5(raw); }

3.3 Python 复刻加密函数与完整登录爬虫代码

python

运行

import hashlib import requests import time class MD5SignLoginCrawler: def __init__(self): # 逆向JS获取固定盐值 self.secret_key = "k9s20df37gglp0x" self.login_url = "https://target.com/api/login" self.session = requests.Session() self.headers = { "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" } def calc_md5_sign(self,user,pwd,ts): """复刻前端MD5加盐签名算法""" raw_str = user + pwd + str(ts) + self.secret_key md5_res = hashlib.md5(raw_str.encode("utf-8")).hexdigest() return md5_res def auto_login(self,username,password): """自主生成签名,提交登录获取加密Cookie""" ts = int(time.time()) sign = self.calc_md5_sign(username,password,ts) post_data = { "username":username, "password":password, "timestamp":ts, "sign":sign } resp = self.session.post(self.login_url,data=post_data,headers=self.headers,timeout=8) if resp.status_code == 200 and resp.json().get("code") == 200: print("登录成功,已自动保存加密登录Cookie至session") cookie_dict = self.session.cookies.get_dict() print("当前有效登录Cookie:",cookie_dict) return True else: print("登录失败,签名或参数异常") return False if __name__ == "__main__": craw = MD5SignLoginCrawler() craw.auto_login("test_account","123456abc")

3.4 代码原理拆解

  1. 严格沿用逆向所得盐值与字符串拼接顺序,字符编码统一 utf-8,保证 MD5 结果与前端 JS 完全匹配;
  2. 使用 requests.Session 自动托管登录下发的加密 Cookie,后续业务请求直接复用会话实例;
  3. 时间戳实时生成,规避固定时间戳导致的签名过期失效问题。

四、场景二:AES 对称加密登录 Cookie 逆向实现

4.1 AES 加密逻辑说明

前端采用 AES-CBC 加密模式,固定 16 位密钥 key 与 16 位偏移向量 iv,账号、密码明文经 AES 加密后作为请求参数,后端使用同源 key 与 iv 解密,校验账号合法性后下发加密 Cookie。逆向重点从 JS 中提取 key、iv、填充规则、编码格式。

4.2 前端 JS 加密源码(逆向提取)

javascript

运行

//逆向获取AES配置参数 var aes_key = "16bitskey0000000"; var aes_iv = "iv16bit00000000"; function aesEncrypt(rawText){ //CBC模式、pkcs7填充、base64输出密文 }

4.3 Python AES 加密复刻与登录实现

python

运行

from Crypto.Cipher import AES from Crypto.Util.Padding import pad import base64 import requests class AESLoginCrawler: def __init__(self): self.key = b"16bitskey0000000" self.iv = b"iv16bit00000000" self.login_api = "https://target.com/aes/login" self.sess = requests.Session() def aes_cbc_encrypt(self,raw_text): """复刻前端AES-CBC加密逻辑""" cipher = AES.new(self.key,AES.MODE_CBC,self.iv) raw_byte = raw_text.encode("utf-8") padded_data = pad(raw_byte,AES.block_size) encrypt_data = cipher.encrypt(padded_data) cipher_base64 = base64.b64encode(encrypt_data).decode("utf-8") return cipher_base64 def login_by_aes(self,user,pwd): enc_user = self.aes_cbc_encrypt(user) enc_pwd = self.aes_cbc_encrypt(pwd) payload = {"username":enc_user,"password":enc_pwd} res = self.sess.post(self.login_api,json=payload,timeout=7) if res.json().get("success"): print("AES加密登录成功,会话Cookie已自动保存") return self.sess.cookies print("AES加密登录失败") return None if __name__ == "__main__": obj = AESLoginCrawler() obj.login_by_aes("spideruser","pass123654")

4.4 关键实现要点

  1. AES-CBC 要求密钥、偏移向量长度必须为 16 字节,和前端 JS 配置保持一致;
  2. 采用 pkcs7 填充对齐分组长度,密文 base64 编码后传输,和前端输出格式统一;
  3. 加密参数错误会直接触发后端解密异常,返回登录拒绝,逆向时不可随意修改 key 与 iv。

五、场景三:RSA 非对称加密登录凭证逆向

5.1 RSA 加密业务逻辑

前端使用平台公钥对明文密码加密,后端持私钥解密校验密码,公钥明文暴露在前端 JS 中,爬虫逆向提取公钥即可自主完成密码加密,提交登录获取 Cookie。RSA 特征:公钥加密、私钥解密,私钥仅存放后端无法逆向获取。

5.2 Python RSA 加密实现代码

python

运行

from Crypto.Cipher import PKCS1_OAEP from Crypto.PublicKey import RSA import base64 import requests class RSALoginCrawler: def __init__(self): # 逆向前端提取RSA公钥字符串 self.pub_key_str = """-----BEGIN RSA PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCFENGw33yGihy92pDjZQhl0C3 6PJrlrvfSKQjXifSx1WuuFjpxX5u3vYj+BqbD1dA2YcCotbl959aksgn3jR38W9D RQLafY2kXAKvNOC1RXZZbOFKAypDvt1FmnL4R593+D45oq5Mj5pqG+zcUELRmlpb4 xy3szGCOUDfaDufIYfwIDAQAB -----END RSA PUBLIC KEY-----""" self.login_url = "https://target.com/rsa/login" self.session = requests.Session() def rsa_pwd_encrypt(self,raw_pwd): pub_key = RSA.import_key(self.pub_key_str) cipher = PKCS1_OAEP.new(pub_key) enc_byte = cipher.encrypt(raw_pwd.encode("utf-8")) return base64.b64encode(enc_byte).decode() def auto_rsa_login(self,account,pwd): enc_pwd = self.rsa_pwd_encrypt(pwd) data = {"user":account,"password":enc_pwd} resp = self.session.post(self.login_url,data=data) if resp.json()["code"] == 1: print("RSA加密登录完成,成功获取加密登录Cookie") return self.session.cookies return None if __name__ == "__main__": rsa_crawl = RSALoginCrawler() rsa_crawl.auto_rsa("testacc","mima123")

六、execjs 直跑前端 JS,免复刻快速生成 Cookie

部分站点加密逻辑冗长、多层函数嵌套,手动复刻成本偏高,可直接提取完整加密 JS 代码,通过 execjs 在 Python 环境调用原生 JS 运算,1:1 还原浏览器加密结果。

python

运行

import execjs import requests # 逆向扒取完整加密JS源码 js_code = """ function getSign(name,pw,t){ var s = "k9s20df37gglp0x"; function md5(s){/*省略前端md5实现代码*/} return md5(name+pw+t+s); } """ class JsDirectLogin: def __init__(self): self.ctx = execjs.compile(js_code) self.sess = requests.Session() self.login_api = "https://xxx.com/login" def get_js_sign(self,user,pwd,ts): return self.ctx.call("getSign",user,pwd,ts) def login(self,usr,pwd): import time ts = int(time.time()) sign = self.get_js_sign(usr,pwd,ts) res = self.sess.post(self.login_api,data={"u":usr,"p":pwd,"t":ts,"sign":sign}) print("JS原生加密登录Cookie:",self.sess.cookies) if __name__ == "__main__": jscrawl = JsDirectLogin() jscrawl.login("user01","pass654")

实现优势

无需逐行翻译加密算法,规避 Python 与 JS 数据类型差异带来的加密结果不一致问题,适合复杂混淆 JS 加密场景。

七、登录 Cookie 持久化存储与过期自动续登

加密生成的登录 Cookie 存在有效期,通过 JSON 文件 / Redis 持久化存储 Cookie,每次请求前校验有效性,失效自动调用加密登录函数刷新凭证。

python

运行

import json import os def save_cookie(cookie_dict,file_path="login_cookie.json"): with open(file_path,"w",encoding="utf-8") as f: json.dump(cookie_dict,f,ensure_ascii=False) def load_cookie(file_path="login_cookie.json"): if not os.path.exists(file_path): return None with open(file_path,"r",encoding="utf-8") as f: return json.load(f)

业务调用逻辑:加载本地 Cookie,访问测试接口,返回未登录状态则重新加密登录生成新 Cookie 并覆盖保存。

八、逆向常见坑点与故障处理方案

表格

故障现象问题成因解决方案
Python 加密密文和前端不一致字符编码、填充规则、盐值提取错误逐行比对 JS 拼接顺序,统一 utf-8 编码,核对 AES 填充方式
RSA 加密报错超长RSA 单次加密明文长度受限拆分密码分段加密或改用前端约定分段规则
生成签名正确依旧登录失败存在 UA、设备指纹隐藏校验同步浏览器 UA,补齐 header 内隐性设备参数
Cookie 短期内失效内嵌时效加密字段,每次请求动态刷新封装拦截接口,自动抓取新下发 Cookie 并落地存储
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/4 20:34:04

面试官问:RAG 到底解决了什么问题?90% 的人理解都错了

面试官问:RAG 到底解决了什么问题? 我猜你的第一反应是:让 AI 能搜索外部知识库呗。 错了。 搜索只是 RAG 最浅的一层。RAG 真正在解决的问题是让 LLM 的输出可溯源、可审计、可纠正。如果只是搜索,你用 Elasticsearch 接一下就…

作者头像 李华
网站建设 2026/6/4 20:31:22

基于Arduino与BVM的简易呼吸机:开源应急方案设计与实现

1. 项目概述与核心思路在医疗资源紧张的特殊时期,如何利用现有技术和材料,快速构建一种可靠、低成本的生命支持设备,是工程师们面临的一项紧迫挑战。呼吸机,作为维持危重症患者呼吸功能的核心设备,其复杂性和高昂成本往…

作者头像 李华
网站建设 2026/6/4 20:31:13

Arduino起重机DIY:从纸板结构到电机控制的完整实践指南

1. 项目概述:为什么选择用Arduino搭建起重机?如果你对机器人、自动化或者嵌入式系统感兴趣,但又觉得入门门槛太高,不知道从哪里开始动手,那么这个用Arduino搭建一个简易起重机的项目,可能就是你一直在找的“…

作者头像 李华
网站建设 2026/6/4 20:30:38

QuickBMS深度解析:3大核心功能解锁游戏资源提取新境界

QuickBMS深度解析:3大核心功能解锁游戏资源提取新境界 【免费下载链接】QuickBMS QuickBMS by aluigi - Github Mirror 项目地址: https://gitcode.com/gh_mirrors/qui/QuickBMS 在数字内容创作和游戏开发领域,文件格式的多样性常常成为技术探索…

作者头像 李华
网站建设 2026/6/4 20:29:54

RhinoPython脚本编程完整指南:解锁3D建模自动化的终极方案

RhinoPython脚本编程完整指南:解锁3D建模自动化的终极方案 【免费下载链接】rhinoscriptsyntax rhinoscriptsyntax library for Python scripting engine that runs on both the Windows and OSX Rhino as well as Grasshopper 项目地址: https://gitcode.com/gh_…

作者头像 李华
网站建设 2026/6/4 20:25:35

小程序开发多少钱:2026成本构成与平台选型全维度解析

2026年小程序生态持续扩张,微信小程序用户规模已达9.49亿,越来越多商家将小程序作为数字化经营标配,但小程序开发多少钱成为多数商家的首要困惑。从基础展示到全功能商城,价格跨度极大,费用差异源于开发模式、功能配置…

作者头像 李华