欢迎光临散文网 会员登陆 & 注册

[深入系列]MCJE微软正版登录流程#服务器篇

2023-07-08 11:47 作者:WinsreWu  | 我要投稿

# 前言&背景

我之前写了 CV21783605 这篇讲述客户端如何获得 access token, 那么服务器是如何验证玩家的呢? 本篇将会为您解答

# 大体流程

其实mc验证有多种方式 (它那个验证的方法有两个实现, 一个是com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService那里, 一个是com.mojang.authlib.legacy.LegacyMinecraftSessionService那里) 我猜前者是外置登录, 后者是正版, 只是猜而已。这里只讲正版

然后mojang提供了一个api, 让客户端验证自己的身份, 并问客户端要连接那个服务器。而服务器也会请求它, 如果就是客户端要连接的,那么api就会放行。于是验证结束。

以下是客户端尝试加入服务器的几个阶段

HELLO,
KEY,
AUTHENTICATING,
NEGOTIATING,
READY_TO_ACCEPT,
DELAY_ACCEPT,
ACCEPTED;

# 具体实现

由于本人对加密方面知识和别的数学知识了解甚少, 有些内容我不得不略过(或是只提供猜测), 有大佬可以在评论区补充。

首先是Hello阶段:

(注: 我删掉了一些不太重要的代码)

首先客户端会给服务端发自己的profile, 大概就是个玩家的uuid + name, 服务器会判断是否要登陆(是不是离线模式),然后决定直接放行还是走验证流程。这里会给一个public key, 这里我猜是个非对称加密, 还会带一个nonce, 也是个验证手段

这里前半段是自己生成了个private key,然后直接当标识符和server生成的public key以及那个nonce给hash了一下(就是那个generateServerId, 这个的实现就是个sha-1),最后发给了一个mojang的api https://session.minecraft.net/game/joinserver.jsp 然后会开个加密(这里我没看懂其实现, 应该是用了之前发的那个public key把自己生成的private key加密了, 但我不确定)

发的这个操作是由joinServerSession实现的

此处的JOIN_URL是 https://session.minecraft.net/game/joinserver.jsp 。其中那个concatenateURL就是把那个map里面的东西变成 .../joinserver.jsp?user=...&sessionId=...&serverId=...

然后api会返回一个表示, ok就是成功

这时就到了KEY阶段

服务器会把客户端发的那个private key解密(真就把key当标识符了), 然后就开始Authenticating阶段

然后给各位看一下那个hasJoinedServer方法

和之前那个joinServer一样, 但是CHECK_URL是 session.minecraft.net/game/checkserver.jsp?user=...&serverId=...

serverId应该和客户端那个一样。如果一样,他就会yes, 验证通过,服务器就会把状态变成ready to accept。然后就是在tick的时候进行一些黑名单, 服务器满员什么的检查, 然后就accepted。

没了

# 样例

我: session.minecraft.net/game/joinserver.jsp?user=张三&sessionId=用上一个专栏的python文件产生的密钥&serverId=114514

api: 过

我: session.minecraft.net/game/checkserver.jsp?user=张三&serverId=114514

api: 过

我: 高高兴兴玩服务器咯


(ps 那个id好像没有限制 所以可以乱写 只要两边一样就成


[深入系列]MCJE微软正版登录流程#服务器篇的评论 (共 条)

分享到微博请遵守国家法律