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

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

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

林间仙子发布于 2025/1/19更新于 2026/9/1077 浏览
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. 登录接口分析

更多推荐文章

查看全部
  • FLUX.1 镜像部署指南:内置中文界面与场景优化
  • C++ 运算符重载:自定义类型的运算扩展
  • 多模态动态融合模型 PDF:理论解读、代码修复与参数详解
  • gpt-oss-20b 本地 WebUI 部署与网页推理服务配置
  • 前端三年后,我辞职去韩国读了个CS硕士
  • 基于 Leaflet 和天地图的免费运动场所 WebGIS 可视化 - 以长沙市为例
  • ROS2 基础:从零理解 URDF 机器人模型描述格式
  • 用 Python 实现会追着食物跑的 AI 贪吃蛇
  • Claude Code 与 OpenClaw 实战指南:从初始化到自动化工作流
  • Gemini 3 编程能力深度评测:从代码补全到架构级理解
  • 程序员与管理者进阶必读的 5 本经典好书
  • C++ 伸展树与红黑树详解及实现
  • AI 辅助构建高可用电商系统核心架构实战
  • Java Spring 框架初识与 Maven 项目创建指南
  • Ubuntu 22.04 LTS 系统下载指南及国内镜像加速
  • LobsterAI:网易有道开源的 24/7 全天候个人 AI 工作助理
  • VMware Workstation 17 下 Ubuntu 24.04 虚拟机卡死问题排查与解决
  • ChatGPT Prompt Hacker 技巧:优化简历通过 AI 筛选
  • 【JWT】JWT(JSON Web Token)结构化知识体系(完整版)
  • Linux 解压命令实战指南:从 tar 到 7z

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如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