跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Python大前端算法

Steam 登录接口 Protobuf 协议逆向分析

综述由AI生成Steam 登录涉及 RSA 加密与 Protobuf 序列化。逆向过程需定位 input_protobuf_encoded 参数,通过调试找到字段定义结构,还原 proto 文件。获取公钥后用于密码加密,最终构造完整请求。本文解析了 GetPasswordRSAPublicKey 及 BeginAuthSessionViaCredentials 接口流程,提供 Python 实现示例。

林间仙子发布于 2025/1/19更新于 2026/6/1228 浏览
Steam 登录接口 Protobuf 协议逆向分析

目标

对 Steam 登录接口进行逆向分析。 目标网址:https://store.steampowered.com/login/

逆向分析

输入账号密码点击登录后,首先观察接口 GetPasswordRSAPublicKey/v1。从命名可以看出该接口返回 RSA 加密的公钥信息。观察请求参数,核心加密参数为 input_protobuf_encoded。

在浏览器中全局搜索该参数名,可以定位到两处调用位置。可以看到 input_protobuf_encoded 的值经过处理,其源头是 r.JQ(o),而 o 的值为 n.SerializeBody()。这里的 n 是一个包含账号信息的实例对象。

我们可以通过原型链进入构造函数进行断点调试。在 super 位置下断,发现实例化时传入了一个类定义。初始化时会检查 account_name 属性,若不存在则调用特定方法创建对象。

无论是从 n.aR 方法入手,还是追踪 account_name 的属性及其父类,最终都会指向 protobuf 协议的处理逻辑。

Protocol Buffers 基础

Protobuf 协议根据特定的语法定义数据结构,发送和接收数据前必须约定好字段格式。上文中的类正是对 account_name 字段的定义。我们可以参考 JS 代码中的格式编写自己的 .proto 文件。

Protobuf 常见的数据类型包括 int32、string、bool、bytes、message 等。

新建一个 proto 文件(需配置环境),定义 account_name 字段:

syntax = "proto3";
message CAuthenticationGetPasswordRsaPublicKeyRequest {
  string account_name = 1;
}

执行命令 protoc --python_out=. xx.proto 将 proto 文件转为 Python 代码。生成的 py 文件可以直接使用。

使用示例如下:

from loguru import logger
from steam_pb2 import CAuthenticationGetPasswordRsaPublicKeyRequest

def get_rsa_public_key(username):
    message = CAuthenticationGetPasswordRsaPublicKeyRequest(account_name=username)
    logger.info(message.SerializeToString())
    logger.info(type(message))

if __name__ == '__main__':
    get_rsa_public_key("a123456789")

回到逆向流程,我们已经知道了 o 的生成方式,剩下的 r.JQ 方法通常是 Base64 编码。组合起来就生成了 input_protobuf_encoded 的值。

响应信息解析

推荐在 XHR 请求处下断点,跟踪直到看到响应信息解析的地方。l.data 即为响应信息,关键方法是 r.deserializeBinaryFromReader。单步跟踪会进入静态方法 MBF,这里判断 protobuf 数据格式是否已定义,未定义则进行定义。

查看定义的字段,例如 publickey_mod、publickey_exp、timestamp。按照 JS 代码中的字段与类型重新定义 proto 文件:

message CAuthenticationGetPasswordRsaPublicKeyResponse {
  string publickey_mod = 1;
  string publickey_exp = 2;
  uint64 timestamp = 3;
}

完整请求代码

整合上述步骤,完整的 Python 请求代码如下:

import base64
import requests
from steam_pb2 import (
    CAuthenticationGetPasswordRsaPublicKeyRequest,
    CAuthenticationGetPasswordRsaPublicKeyResponse
)

headers = {
    'user-agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
}

def get_rsa_public_key(username):
    origin = 'https://steamcommunity.com'
    message = CAuthenticationGetPasswordRsaPublicKeyRequest(account_name=username)
    protobuf = base64.b64encode(message.SerializeToString()).decode()
    url = f'https://api.steampowered.com/IAuthenticationService/GetPasswordRSAPublicKey/v1'
    params = {
        "origin": origin,
        "input_protobuf_encoded": protobuf
    }
    response = requests.get(url, params=params, headers=headers, timeout=3)
    
    # 解析响应信息
    response_obj = CAuthenticationGetPasswordRsaPublicKeyResponse.FromString(response.content)
    print(response_obj)
    return response_obj.publickey_mod, response_obj.publickey_exp, response_obj.timestamp

if __name__ == '__main__':
    get_rsa_public_key("a123456789")

至此,第一个接口的请求参数与响应信息都已搞定。返回的三个参数 publickey_mod、publickey_exp、timestamp 明显用于后续 RSA 加密。

登录接口分析

接下来是真正的登录接口 BeginAuthSessionViaCredentials/v1。该接口参数只有一个 input_protobuf_encoded。同样在老地方下断,根据 t 值判断接口。

找到约定字段的地方进行改写,主要字段包括 device_friendly_name、account_name、encrypted_password 等。注意 device_details 属于自定义类型,需要单独查找其结构定义。

密码是被加密过的,加密方法推断为 RSA,使用上一步获取的 publickey_exp 和 publickey_mod 作为模数与指数。响应数据的解析方法同上,不再赘述。

至此,整个逆向流程结束。

目录

  1. 目标
  2. 逆向分析
  3. Protocol Buffers 基础
  4. 响应信息解析
  5. 完整请求代码
  6. 登录接口分析
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 论文阅读:FR-LLM 多任务大模型用于联合故障诊断与 RUL 预测
  • Web 自动化测试入门:从概念到百度搜索实战
  • Windows 下部署 OpenClaw 并接入飞书机器人实战
  • DeepSeek-R1-Distill-Qwen-1.5B 本地部署:vLLM+Open-WebUI 环境搭建
  • 腾讯混元大模型 AIGC 系列产品深度体验
  • CodeX 二次验证手机号
  • 若依(RuoYi)低代码框架深度剖析与选型指南
  • JNI 开发陷阱:C++ Debug 正常为何 Release 返回 NaN
  • 吴恩达开源 aisuite 项目介绍与使用指南
  • 大学生论文写作:AI 工具全流程实战指南
  • Windows 系统安装与配置 Neo4j 图数据库指南
  • Python PDF 生成实战指南:fpdf2 全方位应用
  • DALL·E 3 图像生成功能与 API 使用指南
  • C++ ODB ORM 入门与实战应用
  • OpenClaw AI 智能体部署与使用指南
  • Flutter 在 OpenHarmony 上集成 wasm_ffi 实现高性能 WASM 交互实战
  • AI 绘画体验:Midjourney 入门与原理
  • C++ 多态底层实现原理详解:虚函数表与对象模型
  • Git 版本控制快速入门详解
  • 用初中数学理解 LLM 工作原理

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online