长期不变的通信密钥是协议安全的短板:一份被逆向出的密钥可以让攻击者伪造所有后续封包。会话密钥轮换的目标是"每段会话、每个周期使用不同密钥,泄露影响被时间与范围截断"。适用于游戏登录握手、充值通道、跨服通信三类链路。
密钥不由客户端单方面决定,而是登录时由服务器生成并安全下发:
-- 服务器(登录成功后)
local sessionKey = randomHex(32)
local payload = aes_encrypt(deviceKey, sessionKey) -- 用设备绑定密钥包一层
sendTo(client, { cmd = "KEY_EXCHANGE", data = payload, expires = os.time() + 30 })
-- 客户端
local sessionKey = aes_decrypt(deviceKey, msg.data)
assert(msg.expires > os.time(), "密钥交换已过期")
conn:setKey(sessionKey)
三层设计:会话密钥每次登录随机生成(泄露不跨会话);下发时用设备绑定密钥再包一层(抓包拿不到明文);30 秒过期窗口(超时未确认作废重发)。
会话内每 30 分钟轮换一次。轮换采用"新密钥预下发、双密钥并行":服务器先用旧密钥下发新密钥,等客户端 ACK 确认后切换;切换后 60 秒内新旧两把都接受验签,60 秒后只留新密钥。这个窗口设计解决了两个现实问题——客户端恰好在轮换瞬间掉线重连(重连走全新握手,互不影响),以及 ACK 丢失导致的单侧切换(并行期兜住)。
第一,密钥材料来源用密码学随机(服务端 /dev/urandom),禁止 math.random 拼接——它的序列可预测。第二,轮换事件全量留痕(会话 id、时间、成功/失败),密钥相关异常是入侵排查的重要线索。第三,重连与轮换的时序要写测试:模拟"下发新密钥 → ACK 丢失 → 掉线 → 重连"的序列,确认每个状态都能收敛到可用。实测这套流程在 996 单服上轮换开销低于 0.3ms/次,上线一年未出现密钥相关的联机故障,属于一次搭好、长期受益的基建。
本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
设计初衷 世界频道是全服的广场,也是刷屏的重灾区:工作室的广告、抢怪者的互喷、刷屏的喇叭党,把真正有用的组队信息淹没。频道治…
设计初衷 限时道具(7 天时装、30 天坐骑)卖的是"拥有感的时间切片",到期处理决定复购:到期即删是情感事故,永久有效又杀…
设计初衷 限时活动下线后,最怀念它的玩家声音分散在论坛与客服工单里,运营排期只能靠拍脑袋。返场投票把"想不想让它回来"变成结…
底层原理 概率 bug 最难复现:"一万次里错了三次"的报告拿到手,重跑一万次可能一次都不错——因为每次运行的随机序列各不相…
底层原理 性能优化的第一课不是测速,是估算:一段双层循环的耗时 = 外层次数 × 内层次数 × 单次操作成本。100 名玩家…
业务场景 30 天月卡的连续签到奖励(第 7、14、30 天大奖)被一次忘签打断,玩家怒而弃游。补签机制:断签当日不立刻断掉…