Skip to content

Instantly share code, notes, and snippets.

@burningtnt
Last active November 26, 2025 14:48
Show Gist options
  • Select an option

  • Save burningtnt/28a8e8ae4aadceffc17b1dd1333c980a to your computer and use it in GitHub Desktop.

Select an option

Save burningtnt/28a8e8ae4aadceffc17b1dd1333c980a to your computer and use it in GitHub Desktop.
为什么联机时会有【无效的玩家档案公钥签名,请尝试重启游戏】错误
image

省流

当下列条件全部满足时,【无效的玩家档案公钥签名,请尝试重启游戏】错误出现:

  1. 房客使用第三方皮肤站账户登录(或启用了 HMCL 的离线换肤功能);
  2. 房客成功获取了 个人信息公钥签名(下简称 签名);
  3. 房客的 UUID 符合离线账户 UUID 标准格式UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes(StandardCharsets.UTF_8)));
  4. 房客使用 Terracotta | 陶瓦联机 提供的联机大厅进入房间,绕过了正版验证;
  5. 房主使用局域网开放功能。
  6. 房主使用正版验证或离线账户。

不满足上述任意一条条件,房客将被正版验证挡下,或正常进入房间。

正经分析

Minecraft 在完成密钥交换后,服务端将执行正版验证。 如果正版验证失败(条件 #1 #6),客户端和服务端都不会断开连接(条件 #4 #5),而是通过离线账户 UUID 标准格式重新计算玩家 UUID,回传至客户端。

此时,成功获取个人信息公钥签名的客户端(条件 #2)将检查服务器回传的 UUID 是否与当前本地玩家的 UUID 匹配(条件 #3)。 如果匹配,在 Authlib-Injector 的作用下, 客户端将把获取到的签名(实际上是 byte[1])发送至服务端。

服务端收到签名后,将从本地 JAR 中加载硬编码的 Mojang 公钥来验证签名。但由于签名长度为 1 而非 256,验证必定失败。 此时,服务端将主动踢出玩家,并告知客户端【无效的玩家档案公钥签名,请尝试重启游戏】。

为什么大家的好心最终办成了坏事

正确的 Minecraft

Minecraft 在进入多人世界时,会先执行正版验证。如果正版验证失败,客户端将主动结束连接,而服务端将立刻踢出玩家。

但是,如果当前连接的服务器是从局域网中自动发现出来的,并且服务器是局域网开放的客户端, 客户端和服务端都会在正版验证失败后保持连接,继续进行后续步骤。

当完成上述正版验证后,客户端将请求微软服务器获取 个人信息公钥签名。 如果签名获取成功(即当前账户为正版),客户端将主动向服务器递交 个人信息公钥签名。 服务端将用动态获取的证书验证签名以确保 个人信息公钥签名 无误。

如果上述 个人信息公钥签名 验证流程失败,服务器将主动踢出玩家。 如果客户端未提供 个人信息公钥签名 且 服务器强制开启了聊天验证(也称聊天举报)功能,客户端将被禁止发送任何游戏内聊天消息。

通过以上流程,Minecraft 成功实现了:

  • 正版玩家将能够正确进服(既然他们能通过正版验证,个人信息公钥签名 也自然正确);
  • 离线账户将能够在服务器主动关闭了正版验证时进服(离线账户从微软服务器拉取 个人信息公钥签名 时无法通过鉴权,获取的签名为空;
  • 任何玩家能够在没有网络时正常局域网联机(服务器将跳过正版验证)。

正确的 Authlib-Injector

Authlib-Injector 在 ProfileKeyFilter.java 向 Minecraft 提交了一个 byte[1] 的 个人信息公钥签名

response.put("publicKeySignatureV2", "AA==");

同一文件 中,

Signature sig = new Signature("authlib-injector-dummy-verify") {
    ...
    @Override
    protected boolean engineVerify(byte[] sigBytes) {
        return true;
    }
};

抹去了 个人信息公钥签名 的验证过程。

通过以上流程,Authlib-Injector 实现了:

  • 允许正版、第三方皮肤站玩家入服(个人信息公钥签名 的验证过程 被抹去);
  • 允许离线玩家入服(客户端不会发送 个人信息公钥签名 供服务器验证);

正确的 Terracotta | 陶瓦联机(条件 #4 #5)

Terracotta | 陶瓦联机 通过在房客端重新广播房间信息,滥用了 Minecraft 允许局域网联机绕过正版验证的功能。

正确的 HMCL(条件 #3)

为确保兼容性,HMCL 的离线账户使用离线账户 UUID 标准格式,但利用 Authlib-Injector 实现了换肤功能。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment