news 2026/2/6 12:36:35

CPP sign值逆向

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CPP sign值逆向

0x0 引言

app在请求下单的时候会携带一个sign值,这个sign值是通过特定的签名算法生成的加密字符串,主要用于接口安全验证和防篡改保护。

sign:e24c6676f38d3e97178de0808b931781

初步推测可能采用了MD5加密,这并非主流大厂的产品。

通常的生成流程

  • 参数排序:将所有请求参数(除sign本身外)按照参数名的ASCII码从小到大排序

  • 参数拼接:将排序后的参数以"参数名=参数值"的格式用"&"符号连接起来,例如:amount=100&order_id=123456×tamp=1625097600

  • 添加密钥:在拼接后的字符串末尾加上预先约定的API密钥(secret key),如:amount=100&order_id=123456×tamp=1625097600&key=secret_key

  • 加密计算:对最终字符串进行MD5或SHA1等加密运算,生成sign

直接尝试用 Frida 进行 hook 操作:

0x1 frida hook

md5参数值

PWFSJVAEQYUSNDEFNMHSISJISKHSULDESKM5935JVABS2528909106671L9D2A7M0U5Y2T0C2PPC

请求参数

{ "timeStamp": 1766019098252, "nonce": "SBAVJ", "sign": "903fb31cd87c0990b36728a54e049136", "ticketTypeId": 5395, "count": 1, "purchaserIds": "" }

看到这里,心里突然"咯噔"一下,像是被什么东西猛地揪住了。仔细检查了好几遍,发现确实没有对应的参数可以匹配这个操作。手心开始微微冒汗,脑子里闪过各种可能的解决方案。这时,我深吸一口气告诉自己:"别慌,保持冷静"。

突然想到一个有趣的思路:既然正向查找不行,那为什么不试试反向操作呢?或许将字符串倒序输出就能找到突破口。

CPP2C0T2Y5U0M7A2D9L1766019098252SBAVJ5395MKSEDLUSHKSIJSISHMNFEDNSUYQEAVJSFWP

0x2 参数分析

  • 固定值1: CPP2C0T2Y5U0M7A2D9L
  • timestamp: 1766019098252
  • nonce: SBAVJ
  • ticketTypeId: 5395
  • 固定值2:MKSEDLUSHKSIJSISHMNFEDNSUYQEAVJSFWP

经过多次深入分析(包括日志记录、数据比对和单元测试验证),发现固定值1和固定值2在整个程序运行周期内始终保持不变,由于这两个值表现稳定且不影响核心功能,后续有时间的话再进行深入反编译分析

nonce是一个随机生成的5位字符串,主要用于安全验证和防重放攻击

0x3 sign值构造

拼接规则详细说明:

  1. 前缀部分(reverse(prefix))

  2. 票种ID处理(reverse(ticketTypeId))

  3. 随机数处理(reverse(nonce))

  4. 时间戳处理(reverse(timestamp))

  5. 后缀部分(reverse(suffix))

完整示例: 输入参数:

  • prefix = "CPP2C0T2Y5U0M7A2D9L"
  • ticketTypeId = "5395"
  • nonce = "SBAVJ"
  • timestamp = "1766019098252"
  • suffix = "MKSEDLUSHKSIJSISHMNFEDNSUYQEAVJSFWP"

最终拼接结果: reverse(prefix) + reverse(ticketTypeId) + reverse(nonce) + reverse(timestamp) +reverse(suffix)

将拼接的结果再进行md5得到sign

0x4 sign值还原

def _reverse(self, value) -> str: """ 通用倒序方法,数字先转字符串再倒序 """ return str(value)[::-1] def _generate_nonce(self, length: int = 5) -> str: """ 生成随机字符串,默认长度 5 """ return ''.join(random.choices(string.ascii_uppercase, k=length)) def _md5(self, text: str) -> str: """ 计算字符串的 MD5 值,返回小写十六进制 """ return hashlib.md5(text.encode("utf-8")).hexdigest() def generate_sign(self, ticket_type_id: int, nonce: str, timestamp: int) -> str: """ 生成 sign 拼接规则:prefix + reverse(ticketTypeId) + reverse(nonce) + reverse(timestamp) + suffix """ raw_str = f"{self.prefix}{self._reverse(ticket_type_id)}{self._reverse(nonce)}{self._reverse(timestamp)}{self.suffix}" return self._md5(raw_str)

0x5 结论

由于MD5加密算法具有单向不可逆的特性(无法通过哈希值反推出原始数据),因此在服务器端进行签名校验(sign值验证)时,必须要求客户端在请求中提供用于生成签名的原始参数或相关数据。基于此,我们尝试对字符串进行倒序处理。

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

云开发环境(容器版、虚拟机版、桌面版)

华为开发者空间的云开发环境包括容器版、虚拟机版、桌面版三种形态 一、区别及差异 形态使用方式资源隔离性技术基础启动速度容器版通过本地IDE(如VSCode、Cursor、CodeArts)或CLI工具远程连接容器,代码在容器内运行中(容器间独…

作者头像 李华
网站建设 2026/2/2 12:36:54

Kotaemon在科研文献检索中的创新应用

Kotaemon在科研文献检索中的创新应用 在人工智能驱动科研范式的今天,研究者每天面对的是爆炸式增长的学术文献——仅PubMed每年新增超百万篇论文,arXiv上每周也有数千项新成果发布。传统的关键词搜索方式已难以应对这种信息洪流,而单纯依赖大…

作者头像 李华
网站建设 2026/1/31 13:41:15

欢乐斗地主AI助手:从菜鸟到高手的完整实战指南

还在为斗地主游戏中总是输牌而烦恼吗?DouZero_For_HappyDouDiZhu项目为你带来了革命性的解决方案——基于深度强化学习的AI智能助手。这个项目能够实时分析游戏局势,为你推荐最优出牌策略,让你在欢乐斗地主中体验从未有过的游戏乐趣。 【免费…

作者头像 李华
网站建设 2026/2/6 4:24:33

12、Samba配置文件全解析

Samba配置文件全解析 1. Samba基本配置选项 Samba配置文件中有多个关键选项,下面为你详细介绍: - path :该选项也可写成 directory ,用于指定共享目录或打印机的根目录的绝对路径。你可以在Samba服务器上任意选择目录。若连接用户因权限不足或目录不存在而无法切换到…

作者头像 李华
网站建设 2026/2/5 17:34:58

【光伏风电功率预测】基于图神经网络的区域风光功率预测:场站“互相影响”怎么建模?

关键词:图神经网络GNN、区域风光功率预测、风电功率预测、光伏功率预测、场站相关性、时空预测、图注意力GAT、STGCN、DCRNN、Graph WaveNet、Transformer、Informer、多源气象融合、概率预测、P10/P50/P90、虚拟电厂、风光基地、聚合预测、偏差考核、现货交易1. 为…

作者头像 李华
网站建设 2026/2/7 4:17:10

手机号查QQ号终极指南:3步快速找回关联账号

手机号查QQ号终极指南:3步快速找回关联账号 【免费下载链接】phone2qq 项目地址: https://gitcode.com/gh_mirrors/ph/phone2qq 你是否曾经因为忘记QQ号而无法登录?或者需要确认某个手机号是否绑定过QQ账号?现在,通过phon…

作者头像 李华