news 2026/10/16 5:36:28

lolPing房间如何做到端到端加密:scrypt、AES-256-GCM与Nostr中继全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
lolPing房间如何做到端到端加密:scrypt、AES-256-GCM与Nostr中继全解析

【免费下载链接】lolPing

League of Legends ping wheel for your Windows desktop. Hold Alt, drag, and ping anywhere, with the original animations and sounds.

项目地址:https://gitcode.com/gh_mirrors/lo/lolPing
点击查看免费下载

lolPing 是一款让《英雄联盟》信号(ping)出现在整个桌面的工具,按住 Alt 拖动即可在任何应用上方发出带原声动画的信号。多人"房间"功能允许朋友之间互相看到对方的信号,而所有房间消息都经过端到端加密——即使信号要绕经公网 Nostr 中继,中继方也只能看到无法解读的密文。这篇文章完整解析 lolPing 房间加密的技术路径:从房间码出发,经过 scrypt 密钥派生、AES-256-GCM 加密,最终通过 Nostr 公网上线,带你看清每一层是如何守护你的 ping 的。

一、为什么房间信号需要端到端加密 🔐

在 lolPing 的Settings → Room页面创建一个房间,会得到类似PING-7KQ4M-2HXTR的房间码。把它发给朋友后,每个人的屏幕上都会出现对方的信号(位置按各自分辨率等比换算)和昵称。

房间有两条网络路径:

  • 同一局域网:通过 UDP 直连,走 src/main/lanTransport.ts;
  • 不同网络:加密数据包被封装成 Nostr 事件,经由 6 个免费公共中继转发,走 src/main/relayTransport.ts。

第二条路径意味着你的数据要"路过"第三方服务器。如果信号内容明文传输,中继运营方就能看到你 ping 了什么、在哪 ping、你叫什么名字。所以 lolPing 选择了端到端加密:数据在发送方就变成密文,只有持有房间码的人能解开。

二、房间码:一个"敢念出口"的密码

房间码是整套加密体系的根。它的生成规则在 src/shared/roomCode.ts:

  • Crockford Base32 编码:字母表0123456789ABCDEFGHJKMNPQRSTVWXYZ刻意去掉了 I、L、O、U,避免口头传递时 "B/8"、"O/0" 混淆;
  • 10 位字符:9 位随机 + 1 位校验位;
  • Luhn mod 32 校验位:能捕获任何单字符输错,以及大多数两位交换错误——输错一个字母,加入时会直接提示mistyped而不是静默失败。

解析逻辑 parseRoomCode() 还很宽容:聊天消息里夹带、全角字符、O/I 误输成 0/1 都能识别出来,方便你直接把朋友发的整段话贴进"Join from clipboard"。

三、从房间码到密钥:scrypt 派生的门道 🔑

拿到 10 位标准码后,deriveRoomKeys() 用两步把它变成两套密钥:

第 1 步:scrypt 慢哈希生成主密钥。参数是N = 2^15, r = 8, p = 1,盐值固定为lolping/room/v1,输出 32 字节主密钥。

为什么不用普通哈希?因为中继订阅话题(relay topic)也是从房间码派生的。如果派生函数计算太快,攻击者拿到一个 topic 后就能大规模离线暴力和房间码对账。scrypt 是内存密集型函数(memory-hard),每次尝试都要占用 32 MB 内存,把"猜码"这件事在经济上直接判了死刑。

第 2 步:HKDF-SHA256 把主密钥拆成两个"专钥"。

派生标签用途
msgmsgKey,AES-256-GCM 的消息加密密钥,永不离开主进程
sig-roomrelayTopic,64 位十六进制的中继订阅话题

这就是"one key, one job"原则:即使其中一个用途的密钥泄露,也不会牵连另一个。而且relayTopic本身就是 64 位随机值的十六进制——没有房间码的人看到它,和看一串雪花噪点没有区别。

四、AES-256-GCM:一个信号包是如何被加密的

每条消息(presence 成员信息、ping 信号、emote 表情、bye 离开通知)在 src/main/roomCrypto.ts 中被seal()打包,格式只有四种字段拼起来:

[ 0x01 格式标记 ][ 12 字节随机 nonce ][ AES-256-GCM 密文 ][ 16 字节 auth tag ]

三个关键设计点:

  1. 每条消息一个全新随机 nonce(randomBytes(12))。GCM 模式下 nonce 重用是灾难性的,随机 nonce 把这个问题彻底绕开;
  2. 格式标记字节同时作为 AAD(附加认证数据)。接收端open()会校验这个字节,防止攻击者用"格式合法的别的东西"替换真实包;
  3. GCM 自带完整性校验。密文被篡改哪怕一个比特,16 字节 auth tag 校验就会失败,open()直接返回null丢弃——加密与防篡改一次到位。

包体有硬上限:MAX_PACKET = 1200字节,更大的包既不会发送也不会被读取,这既是 UDP 友好的尺寸控制,也天然限制了单包体积攻击面。

五、Nostr 中继:只运密文的"公共邮筒" 📡

跨网络时,加密包如何送达?答案是把每个 ≤1200 字节的密封包 base64 编码后,装进一个Nostr 事件里(src/main/nostrEvent.ts):

  • kind = 24747:落在 Nostr 的 ephemeral(临时事件)区间 20000–29999。按协议约定,中继只转发、不落盘,会话结束后不留任何历史;
  • tagx= relayTopic:所有成员订阅同一话题,一次 publish 全员可见,成员之间互相看不到 IP;
  • 每次加入房间都现生成一对 secp256k1 密钥,用 NIP-01 规范对事件签名。签名只是满足中继的"防冒名"要求,真正的安全由房间自己的加密体系负责——所以密钥用完即弃;
  • 中继清单:src/main/relays.ts 里的 6 个公共中继是用 tools/relay-probe 从 16 个候选里筛出来的(能接受 kind 24747、30 秒内 5 事件/秒无限流、10 分钟持续连接不掉线)。任何成员只要和另一个成员共享一个可用中继就能互通。代码里还留了一条兼容性铁律:未来版本必须保留旧列表里至少 3 个中继,否则新旧版本互相找不到。

六、隐私边界:中继到底能看到什么?

中继能看到中继看不到
内容—✅ ping 内容、emote、昵称(全是密文)
身份你的 IP 地址、一个匿名的 64 位房间话题✅ 房间码、成员列表
行为你何时在发消息✅ 发了什么

局域网成员之间只能看到彼此的内网 IP。如果完全不想让数据碰公网,把设置里的Allow internet connections关掉即可,房间退化为纯局域网模式。

七、纵深防御:重放、限速与成员管理 🛡️

加密只是第一层。src/main/roomManager.ts 上还叠了几道闸:

  • 序列号防重放:每条消息带seq序号,配合 replayGuard.ts 识别并丢弃重放的旧包;
  • 中继限速:共享中继上每位发送者限 5 包/秒、突发 10 包——因为一次 publish 全员可见,公共中继对流量极其敏感;
  • 接收限制:设置页可给每个成员单独调"收到的 ping/emote 上限",还能静音单人或整个房间;
  • 房间容量 8 人,踢人方式:退出后重建新房间。

八、代码地图:想深挖从哪读起 📖

模块文件职责
加密核心src/main/roomCrypto.tsscrypt 派生 + AES-256-GCM 密封/开启
房间码src/shared/roomCode.ts生成、校验、容错解析
消息协议src/shared/roomProtocol.tspresence/ping/emote/bye 定义与校验
成员管理src/main/roomManager.ts路由选路、限速、超时踢人
中继传输src/main/relayTransport.ts加密包 ↔ Nostr 事件
中继清单src/main/relays.ts6 个经过实测的公共中继
测试tests/main/relayRoom.test.ts、tests/shared/roomCode.test.ts房间协议与加密测试

架构细节(路径选择、超时参数、中继判活策略)在 docs/design.md 有完整论述,单机组一台电脑想体验房间的话,可以用 tools/room-peer 脚本扮演一个随机 ping 的假成员试试。

一句话总结 lolPing 的加密哲学:房间码是唯一秘密——scrypt 让它算不快,HKDF 让它一分两用,AES-256-GCM 让内容密不透风,Nostr ephemeral 事件让密文不留痕。你只需要把 10 个字符告诉朋友,剩下的,数学来处理。

【免费下载链接】lolPing

League of Legends ping wheel for your Windows desktop. Hold Alt, drag, and ping anywhere, with the original animations and sounds.

项目地址:https://gitcode.com/gh_mirrors/lo/lolPing
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/16 5:36:01

DLSS Swapper 完整教程:一键安装,替换与回滚游戏 DLSS 版本

DLSS Swapper 完整教程:一键安装,替换与回滚游戏 DLSS 版本 【免费下载链接】dlss-swapper 项目地址: https://gitcode.com/GitHub_Trending/dl/dlss-swapper DLSS Swapper 是一款面向 Windows 玩家的画质增强 DLL 管理工具,可以下载…

作者头像 李华
网站建设 2026/10/16 5:35:17

二级WPS表格基础全解析:工作簿与单元格高频考点指南

考二级WPS的朋友,尤其是自学备考的同学,往往会有一种错觉:表格基础嘛,不就是新建个表格、敲几个字、调调行高列宽,有什么好学的?可等你真正进了考场,打开操作题界面,对着“考生文件夹…

作者头像 李华
网站建设 2026/10/16 5:35:06

ReID损失函数原理与工业级实现:从Triplet到Circle Loss

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/16 5:33:23

VMware NAT模式虚拟机联网配置与克隆网络处理实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华