作者:UpSGE

前言

本文研究了从启动游戏到加入服务器的验证过程(在线模式),并给出了相关的应用示例。

验证过程

服务端启动阶段

Velocity

Vanilla

启动器登入阶段

客户端启动阶段

加入服务器阶段

  1. 客户端生成 共享密钥,服务端生成随机 serverId
  2. 客户端与服务器交换 共享密钥Username服务器公钥serverId
  3. 客户端和服务端使用 serverId共享密钥服务器公钥 计算 服务器哈希
  4. 客户端将 AccessTokenUUID服务器哈希 发送到 Join API ,若 AccessTokenUUID 验证通过,服务器返回 204 响应,否则客户端提示 无效会话
  5. 服务端将 Username服务器哈希 发送到 hasJoined API ,若 Username服务器哈希 验证通过,则返回 服务端UUID服务端Username签名材质,否则客户端提示 尚未登入至 Minecraft 账户(该提示可由服务端自定义)
  6. 服务端将 服务端UUID服务端Username 发给客户端,客户端加入服务器,服务端将 签名材质 广播给所有玩家

后续

Vanilla 服务端验证玩家档案公钥签名

  1. 客户端发送 CHAT_SESSION_UPDATE
  2. 服务端使用 Mojang公钥 验证 玩家档案公钥签名
  3. 若验证不通过,服务端将玩家踢出服务器,客户端提示 无效的玩家档案公钥签名

客户端加载皮肤

  1. 客户端接收到 签名材质 广播
  2. 客户端使用 Mojang公钥 验证 签名材质 是否有效,并判断材质 URL 是否在白名单内
  3. 若验证不通过,客户端将不加载该玩家的皮肤

离线模式

客户端

服务端

应用分析

  1. 注意到 Join APIhasJoined API 是两个独立的 API,且是否允许进服最终取决于 hasJoined API 的验证结果。通过改变 hasJoined API 端点,API 可以控制玩家是否可以加入服务器。
  2. 服务器中的实际 服务端UUID 与客户端的 UUID 无关,仅从 hasJoined API 中获取。这可以用于实现玩家身份的映射。
  3. 玩家在服务器中显示的皮肤完全由服务端决定,服务端可以通过提供有效的 签名材质 来控制玩家的皮肤显示。
  4. 通过改变客户端与服务端的各种 API 端点,可以实现私有的玩家档案管理系统。

相关项目

参考