OfflineAuth — 离线模式防伪身份验证 Mod

版本: 1.0.1

支持: Minecraft 1.21 + Fabric

简介: 防止离线模式下玩家冒名顶替，使用 EdDSA (Ed25519) 签名验证。

目录

概述

工作原理

安装

配置

密钥管理

快速上手

常见问题

技术说明

许可证

概述

Minecraft 默认的离线模式 online-mode=false) 允许任何玩家以任意用户名进入服务器，这使得冒名顶替极其容易。

OfflineAuth 通过挑战-签名-验证机制，让每个玩家拥有唯一的 EdDSA 密钥对：

服务端保存一个 玩家名 → 公钥 的映射表

客户端持有私钥，用来证明自己的身份

登录时服务端发送随机挑战，客户端签名后返回，服务端用公钥验签

只有持有对应私钥的玩家才能以该用户名登录，彻底杜绝改名冒充。

工作原理

服务端 客户端

│ │

│ ── 客户端尝试登录 ──→ │

│ │

│ 1. 服务端查找该玩家名的公钥 │

│ · 找到 → 继续 │

│ · 未找到 → 踢出："未注册的玩家" │

│ │

│ 2. 服务端生成 32 字节随机挑战 │

│ ── 发送挑战 ──→ │

│ │

│ 3. 客户端用私钥签名挑战

│ │

│ ←── 返回签名 ── │

│ │

│ 4. 服务端用公钥验签 │

│ · 验证通过 → 允许登录 │

│ · 验证失败 → 踢出："身份验证失败"│

│ │

安装

服务端

将 offlineauth-1.0.1.jar 放入服务端的 mods/ 目录

确保服务端安装了 Fabric Loader ≥0.15.0 和 Fabric API

启动服务端

首次启动会自动生成示例配置文件 config/auth_keys.json

按下方 配置 步骤添加玩家公钥

客户端

将 offlineauth-1.0.1.jar 放入客户端的 mods/ 目录

确保客户端安装了 Fabric Loader ≥0.15.0 和 Fabric API

将你的私钥文件 private_key.pem 放入客户端的 config/ 目录

启动游戏

提示: 服务端和客户端都需要安装此模组，但 jar 是同一个文件。

配置

服务端配置

文件: config/auth_keys.json

{

"玩家名1": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...\n-----END PUBLIC KEY-----",

"玩家名2": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...\n-----END PUBLIC KEY-----"

}

每个玩家一行，键是玩家的游戏名，值是 PEM 格式的公钥

玩家改名后需要同步更新此文件

客户端配置

文件: config/private_key.pem

-----BEGIN PRIVATE KEY-----

MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQ...

-----END PRIVATE KEY-----

客户端只需要私钥文件

私钥绝不能外泄——持有私钥的人就可以以你的身份登录

密钥管理

生成密钥对

使用项目提供的 GenKeys.java 生成：

javac [GenKeys.java](http://GenKeys.java) && java GenKeys

会输出两个文件：

| 文件 | 说明 | 存放位置 |

|------|------|---------|

| private_key.pem | 私钥 | 客户端 config/ |

| public_key.pem | 公钥 | 发给服务器管理员 |

跨服务器使用

你的 私钥只需保存一份，可以进入任意多个已添加对应公钥的服务器

每进入一个新服务器，都需要将 公钥 发给该服务器的管理员

管理员将公钥添加进该服务器的 config/auth_keys.json 后，你即可进入

模组没有中央认证服务器，公钥分发需要玩家自行与服主沟通。

快速上手

对于玩家

# 1. 生成密钥对

javac [GenKeys.java](http://GenKeys.java) && java GenKeys

# → 得到 private_key.pem（自用）和 public_key.pem（给服主）

# 2. 将 private_key.pem 放入客户端 config/ 目录

# 3. 将 public_key.pem 发给想进的每个服务器管理员

对于服务器管理员

# 1. 将 mod jar 放入服务端 mods/

# 2. 启动服务端，生成 config/auth_keys.json

# 3. 从玩家处获取公钥，按格式写入 auth_keys.json

# 4. 重启服务端或执行 /reload（需要其他插件支持）

常见问题

Q: 玩家进入服务器时被踢出"未注册的玩家"

A: 该玩家的用户名没有在服务端 auth_keys.json 中配置，需要联系管理员添加。

Q: 玩家被踢出"身份验证失败（签名错误）"

A: 通常意味着：

客户端使用的私钥与服务端记录的公钥不匹配

玩家可能更换了密钥对但没有更新服务端配置

Q: 玩家改名了怎么办？

A: 在服务端 config/auth_keys.json 中，将玩家名改为新名字即可。公钥可以复用。

Q: 是否需要重启服务端才能生效？

A: 模组在服务端启动时加载配置。如果运行时修改，需要重启。

Q: 支持哪些 Minecraft 版本？

A: 当前版本基于 1.21 编译。1.21.x 小版本需要重新编译（改 build.gradle 版本号）。

技术说明

加密算法: EdDSA (Ed25519)，JDK 标准 KeyPairGenerator.getInstance("EdDSA")

挑战长度: 32 字节（256 位），使用 SecureRandom 生成

反射兼容: 服务端通过遍历 ServerLoginNetworkHandler 的声明字段，按类型 String + 非 static + 非 final + 非 private 自动匹配玩家名字段，兼容所有映射版本

网络通信: 使用 Fabric API 的 ServerLoginNetworking / ClientLoginNetworking，包 ID 统一使用 offlineauth:challenge

构建

# 需要: JDK 21+, Gradle 8.8+

cd OfflineAuthMod

gradle build

# 输出: build/libs/offlineauth-<version>.jar

许可证

MIT License — 随意使用、修改和分发。

OfflineAuth — 让离线模式不再裸奔。