网络安全

bitchat:连服务器都没有,拿什么监管你?——去中心化、免疫审查的蓝牙 Mesh 即时聊天软件

2026-08-04 #隐私保护#Bluetooth LE Mesh#Nostr Protocol#Noise Framework#P2P#E2E Encryption#iOS / macOS / Android

1. 它是什么?

bitchat 是一款由 permissionlesstech 团队开发并开源的去中心化点对点聊天应用。它的核心理念可以用三个词概括:无服务器、无互联网、无许可。设备之间通过蓝牙直接组网通信,不需要任何中心化基础设施,不需要注册账号,不需要手机号,甚至不需要有网络信号。

项目自称 “IRC vibes”,这个定位非常精准。如果你经历过 IRC 的黄金年代——90 年代末到 2000 年代初,那时候的互联网聊天就是这样的:匿名加入一个频道,和陌生人天南海北地聊,关掉窗口一切消失,没有历史记录,没有算法推荐,没有”你可能认识的人”。bitchat 把这种纯粹的体验搬到了蓝牙网络上,而且增加了一个 IRC 从未拥有的能力:离线可用

但 bitchat 不止于此。与早期版本的纯蓝牙 Mesh 不同,如今的 bitchat 已经演进为双传输层架构——蓝牙 Mesh 负责离线本地通信,Nostr 协议负责互联网可达的全局通信。这意味着它不仅能让你在没有信号的野外和附近的人聊天,还能在有网络时连接全球的 bitchat 用户。

一句话总结:bitchat = 蓝牙 Mesh 离线通信 + Nostr 协议全球通信 + Noise 端到端加密 + 零注册零服务器,面向隐私、应急和去中心化场景的开源即时通讯应用。

想象这样一个场景

bitchat 没有基站、没有服务器、没有验证码,连手机号都用不上,纯靠空气里乱飞的 2.4GHz 无线电波。某地大型活动突然”断网”,人群里有人把”出口在西北角”这条消息丢进 bitchat,不到三分钟,几千部手机像多米诺骨牌一样完成复制,恐慌瞬间降温。

原理并不玄乎:低功耗蓝牙(BLE)一次能蹦 100 米,每部手机都是一个小小驿站。消息被拆成加密碎片,像裹了黑袋子的快递,谁接力谁都不知道里面装的是情书还是欠条。理论上,从洛杉矶到纽约 3940 公里,需要 3.94 万个”百米冲刺”,只要人口够密,节点够多,情书就能在几小时内”蛙跳”抵达。沙漠、草原、深山老林这种”手机荒”地带,快递也会堵车,但城市里最不缺的就是”人肉蓝牙桩”——地铁闸机口、奶茶店、共享单车站台,处处都是潜在”中继小哥”。

速度呢?同城基本秒到,跨省几分钟到几小时不等。听上去比 5G”拉胯”,可别忘了,它天生免疫”拔网线”。当运营商基站罢工、当 Wi-Fi 路由死机、当某些地区进入”维护模式”,它反而越战越勇——节点越多,带宽越大,像极了那句老话:”人民战争海洋深。”

隐私方面,bitchat 把”社恐”写进基因:没有账号,没有头像,没有云端备份,连聊天记录都只存在自己手机里。别人想查?先破解端到端加密,再凑齐整条蓝牙链路上每一部手机,难度堪比把撒出去的盐一颗颗捡回来。

打开手机蓝牙,把消息扔进人潮,让陌生人帮你完成一次”赛博传烽”——这份浪漫,0 元不限量,还附赠满满成就感。

标签Bluetooth LE Mesh Nostr Protocol Noise Framework P2P E2E Encryption iOS / macOS / Android


2. 双传输层架构

bitchat 最独特的设计在于它的双传输层(Dual Transport)架构。两个传输层实现同一个 Transport 接口,由一个 MessageRouter 统一协调:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
      ┌─────────────────────────┐
│ Application Layer │
└────────────┬────────────┘

┌────────────▼────────────┐
│ MessageRouter │
│ (智能传输选择 & 路由) │
└─────┬─────────────┬──────┘
│ │
Bluetooth 优先 Nostr 回退
┌─────▼─────┐ ┌─────▼─────┐
│ BLE Mesh │ │ Nostr │
│ Network │ │ Protocol │
│ │ │ │
│ · GATT │ │ · 440+ │
│ Central │ │ 中继 │
│ +Periph │ │ · geohash │
│ · 7 hops │ │ 频道 │
│ · Noise XX│ │ · XChaCha │
└───────────┘ └───────────┘
离线·本地通信 在线·全球通信

路由器的决策逻辑非常清晰:

  1. 蓝牙优先 —— 当蓝牙链路可用时,直接使用 Noise 加密会话发送,最快且最私密
  2. Nostr 回退 —— 蓝牙不可达时,通过接收者的 Nostr 公钥,经全球中继网络路由
  3. 智能排队 —— 当两者都不可用时,消息进入队列,等待传输恢复后自动投递

3. 蓝牙 Mesh 网络

bitchat 没有使用蓝牙技术联盟(Bluetooth SIG)官方的 Mesh 规范——那套规范主要面向 IoT 场景(智能灯泡、传感器网络),协议栈较重,对移动设备的功耗和延迟并不友好。相反,bitchat 在 BLE(低功耗蓝牙)的 GATT 和广播通道之上,自己实现了一套轻量级的 Mesh 路由协议。

每台设备既是客户端,也是中继

在 bitchat 的 Mesh 网络中,每台设备同时扮演 GATT CentralPeripheral 两个角色。当你发送一条消息,它不只发给附近的设备,还会被范围内的其他设备接收并转发,像接力赛一样一跳一跳地传递出去。只要中间有足够的设备作为中继,消息可以传递到远超蓝牙标称距离(通常 10-30 米)的地方。

受控泛洪 + 去重

bitchat 采用了”受控泛洪 + 去重”的经典 Mesh 策略,但做了精细的调优:

  • TTL 控制:消息初始 TTL 为 7。密集网络(≥6 条连接)时 TTL 被限制为 5,稀疏链路(≤2 条连接)则保留完整深度
  • 去重:LRU 去重集(1000 条目,5 分钟过期),按发送者、时间戳、类型和负载摘要作为键值丢弃重复消息
  • 抖动:中继节点等待随机 10-220ms(密集网络时更长),让去重机制经常能抢占先机
  • 扇出子集:广播消息只发送给确定性子集(约 log₂(连接度)),而非全部链路,大幅降低冗余流量

分片重组

超过链路 MTU 的数据包会被切分为约 469 字节的分片,每个分片独立中继,在接收端重组(支持 128 个并发重组,30 秒超时,1 MiB 上限)。这意味着即使大文件也能在蓝牙 Mesh 中可靠传输。

拓扑感知路由

公告消息携带最多 10 个直连邻居 ID,为每个节点构建一张浅层拓扑图(60 秒新鲜度)。当存在双向确认的路径时,消息会沿路径源路由;否则回退到泛洪。这种混合策略在效率和健壮性之间取得了平衡。


4. Nostr 协议层

当蓝牙不可用时,bitchat 通过 Nostr 协议实现全球通信。Nostr(Notes and Other Stuff Transmitted by Relays)是一个简单、开放的协议,通过一组分布式中继节点传递消息。bitchat 内置了 440+ 个全球中继节点的目录,支持按地理位置智能选择。

位置频道(Location Channels)

bitchat 利用 geohash(地理哈希)编码创建了分层的位置频道系统,这是一种将经纬度编码为短字符串的方法:

频道级别 Geohash 精度 覆盖范围
block 7 字符 城市街区级
neighborhood 6 字符 社区/区域级
city 5 字符 城市级
province 4 字符 省/州级
region 2 字符 国家/大区域级

这意味着你可以加入你所在街区的频道和邻居聊天,也可以切换到城市级频道参与更广泛的讨论。每个 geohash 区域使用独立的临时加密密钥,增强了隐私性。

私有信封

bitchat 的 Nostr 私有消息使用了一套自有的加密信封格式,而非标准的 NIP-17/NIP-44/NIP-59。它复用了 NIP-17 的 kind 编号但不兼容:

  • 内部消息(kind 14)被加密后放入发送者签名的封缄(kind 13)
  • 封缄再次被加密放入由一次性密钥签名的公开信封(kind 1059)
  • 每个加密字段使用 v2: 前缀 + base64url 编码的 24 字节 nonce + XChaCha20-Poly1305 密文 + 16 字节认证标签
  • 密钥来自 secp256k1 ECDH 和 HKDF-SHA256 派生
  • 时间戳随机偏移 ±15 分钟,防止时间关联分析

⚠️ 注意:Nostr 路径没有前向保密(Forward Secrecy)——如果接收者的静态 Nostr 私钥被泄露,存储在中继上的加密信封可能被解密。这是当前设计的已知限制,prekey 方案正在规划中。


5. 加密与安全

在去中心化通信中,端到端加密不是可选项,而是必选项。bitchat 使用 Noise Protocol Framework(Noise 协议框架)——这与 Signal、WhatsApp 等使用的加密基础框架同源,但实现了更精细的控制。

实时会话:Noise XX 模式

已连接的设备之间使用 Noise XX 握手模式建立会话,提供双向认证和前向保密:

1
2
3
4
5
6
7
8
9
10
11
12
13
// Noise XX 握手模式
XX:
-> e // 发起方发送临时密钥
<- e, ee, s, es // 响应方发送临时密钥 + 加密的静态密钥
-> s, se // 发起方发送加密的静态密钥,完成握手

// 加密原语
DH: X25519 (Curve25519)
Cipher: ChaCha20-Poly1305 (AEAD)
Hash: SHA-256
KDF: HKDF-SHA256

// 自动重新密钥:每 1 小时或 10,000 条消息

三步握手提供:双向认证(双方确认对方身份)、身份隐藏(身份密钥在握手过程中被加密)、抗密钥泄露冒充(即使你的密钥泄露,也无法冒充其他人)。

离线封缄:Noise X 模式

对于离线投递的”信使邮件”,bitchat 使用单向 Noise X 模式封缄——发送者身份在密文内部认证,但这条路径没有前向保密。如果接收者的静态密钥被泄露,未投递的密封邮件可能暴露。

加密层级总结

路径 加密方案 前向保密
蓝牙实时会话 Noise XX (X25519 / ChaCha20-Poly1305) ✅ 有
信使离线邮件 Noise X (静态密钥封缄) ❌ 无
Nostr 私有消息 XChaCha20-Poly1305 + secp256k1 ECDH ❌ 无
公开广播消息 Ed25519 签名(明文 + 签名验证) — 公开内容

6. 存储转发:消息一定能送达

bitchat 面临的核心挑战是:接收者此刻不在范围内怎么办? 为此,它设计了一套四层存储转发机制:

📮 发送者发件箱

未投递的私信保留在本地(每对等方 100 条,24 小时 TTL),重新连接时自动重发,直到收到投递/已读回执或达到 8 次重试上限。发件箱以 ChaChaPoly 密钥密封持久化到磁盘,即使应用被杀也只存密文。

🏃 信使系统(Couriers)

当没有传输路径时,消息被封缄后交给最多 3 个可能遇到接收者的连接节点携带。信使看不到发送者、接收者和内容——唯一的路由信息是一个 16 字节的每日轮换标签。

信使系统借鉴了 DTN(延迟容忍网络)中的 spray-and-wait 策略:

  • 不透明寻址:信使只能看到一个 16 字节的轮换标签(接收者静态密钥和 UTC 日期的 HMAC),不知道发送者、接收者和内容
  • 信任分级:互信好友可存放 5 个信封,任何签名验证的节点可存放 2 个,且好友邮件有保留配额
  • 扩散传播:信封携带副本预算(初始 4,上限 8),信使遇到其他合格信使时交出一半预算,让邮件在移动的人群中扩散而非只骑在一个人身上
  • 投递确认:收到接收者的直接公告时投递并删除;收到中继公告时定向泛洪一份副本

想象一下:你在音乐节上给朋友发消息,朋友不在蓝牙范围内。你的消息被密封后交给了附近的 3 个陌生人携带。当其中任何一个人走到你朋友附近时,消息就会自动投递——而这些陌生人全程看不到消息内容,甚至不知道消息是发给谁的。

🔄 公共历史同步

公共广播消息缓存 1000 条,节点之间每 ~15 秒用紧凑的 GCS 过滤器对账同步,保留窗口 6 小时。走过两个分区的设备会把房间最近历史带给错过的人。缓存持久化到磁盘,设备重启后仍然可服务。

🌐 Nostr 邮箱

bitchat 私有信封存储在 Nostr 中继上,客户端重连时回溯 24 小时,覆盖双方设备同时离线的场景——只要任一方触及互联网就能收信。


7. 身份与隐私

密钥即身份

bitchat 没有账号系统。每台设备在 Keychain 中保存两对长期密钥:

  • Curve25519 静态密钥 —— 用于 Noise 密钥协商,其 SHA-256 指纹是设备的稳定身份标识
  • Ed25519 签名密钥 —— 用于数据包签名

在 Mesh 网络中,设备以 8 字节的短 Peer ID 出现——它是 Noise 静态密钥 SHA-256 指纹的前 8 字节。这个 ID 不是临时的:它在会话、重启和保留 Keychain 的重装之间保持稳定,只有在紧急擦除更换身份时才会改变。

紧急擦除(Panic Wipe)

bitchat 提供了一个极端的隐私保护功能:三击触发紧急擦除,立即清除所有数据——身份密钥、好友列表、携带的信使邮件、加密发件箱、公共历史归档和度量指标。一切归零,仿佛你从未存在。

Tor 集成

bitchat 内置了 Arti(Rust 编写的下一代 Tor 客户端)集成。启用后,所有 Nostr 流量通过 Tor 网络路由,进一步隐藏 IP 地址和网络元数据。这是从蓝牙层的物理隐私到互联网层的网络隐私的完整覆盖。

💡 诚实的隐私披露:bitchat 的白皮书坦诚地指出了当前设计的隐私弱点:8 字节 Peer ID 派生自不轮换的密钥,公告以明文发布静态密钥和昵称,因此被动监听者可以枚举参与者并跨地点追踪设备。轮换的空中身份是正在规划的改进方向。


8. 核心功能一览

功能 说明
💬 IRC 风格命令 支持 /slap/msg/who 等经典 IRC 命令,怀旧感拉满
🎙️ 语音消息 & PTT 支持语音笔记录制和 Push-to-Talk(按讲)模式,语音帧通过 Mesh 分片传输
🖼️ 媒体传输 图片和文件通过 Mesh 分片传输(1 MiB 上限),接收前需明确确认
📍 地理频道 基于 geohash 的分层位置频道,从街区到国家级别自由切换
🔑 好友验证 通过 QR 码扫描进行面对面身份验证,将昵称绑定到指纹
Cashu 集成 支持 Cashu(基于 Lightning Network 的代币协议)的解码与处理
🔒 紧急擦除 三击清除所有数据,一键归零,关键时刻的保命功能
🌐 Tor 路由 内置 Arti 引擎,所有 Nostr 流量可选通过 Tor 匿名路由
LZ4 压缩 消息使用 LZ4 压缩,自适应电池模式优化功耗

9. 应用场景

bitchat 的价值不止于”极客玩具”。在以下场景中,它可能是目前最优雅的解决方案:

灾难应急通信

地震、洪水等灾害发生后,蜂窝网络往往在数小时内瘫痪。救援队伍和受灾群众可以使用 bitchat 建立临时通信网络——不需要任何预先部署,打开应用就能通信。Mesh 的自组网特性意味着人越多网络越强壮。

户外活动与探险

徒步、登山、滑雪——这些场景通常没有手机信号。传统方案是对讲机,但 bitchat 通过 Mesh 中继扩展通信距离,支持文字消息传递坐标、路线等精确信息,远比对讲机的语音通话可靠。

大型活动与集会

音乐节、体育赛事——当数万人聚集,蜂窝网络因过载而崩溃。bitchat 不依赖蜂窝网络,人越多 Mesh 网络反而越强壮(中继节点更多),天然适合高密度人群场景。

隐私敏感通信

记者、律师、活动人士——bitchat 的”无服务器”架构意味着没有元数据可以被收集,没有通信记录可以被调取。可选的 Tor 路由进一步隐藏网络踪迹。在”数据即权力”的时代,这种架构本身就是一种立场。


10. 代码库巡礼

bitchat 是一个工程上非常成熟的项目。以下是来自实际源码仓库的数据:

维度 数据
开发语言 Swift(主)+ Rust(Arti Tor 引擎)
源代码文件 266 个 Swift 源文件
测试文件 201 个测试文件(~1,964 个测试用例)
代码总量 ~42,722 行 Swift 代码
测试覆盖率 全套测试在迁移过程中全程绿色
Nostr 中继 441 个全球中继节点(含 GPS 坐标)
许可证 公共领域(Unlicense)—— 完全自由使用
平台 iOS 16+ / macOS 13+ / Android(Play Store)
架构文档 13 篇专题设计文档(含白皮书 v2.0)

架构演进

bitchat 的代码库经历了清晰的架构演进。从 V1 的单体 BLEService(8,300+ 行的”上帝对象”),到 V2 的应用层解耦(引入 AppRuntime 组合根、ConversationStore 和多个特性模型),再到 V3 的传输层重构(将 BLE 拆分为 BLELinkLayer + Mesh Engine + 特性模块的分层架构),每一步都有详细的设计文档记录。

特别值得注意的是项目的**模拟器优先(Simulator-First)**测试策略:通过 SimulatedLinkLayer 实现 CB-free 的多节点测试拓扑,5 个确定性多节点测试在 ~40ms 内完成——包括公告/绑定收敛、端到端 Noise 建立、线型拓扑中继、重复泛洪去重和紧急轮换单槽重绑等场景。模拟器上线第一天就发现了一个真实 bug。

工程严谨度

从代码库可以看出项目团队对工程质量的极高要求:

  • 队列契约测试BLEQueueContractTests 通过 grep 源码确保只有 onEngine 可以同步进入引擎队列,传输代码永远不会同步分发到主队列
  • SwiftLint + Periphery:代码风格和死代码检测自动化
  • Justfile 构建系统:标准化构建、测试和运行流程
  • 构建验证文档:详细的 VERIFYING-A-BUILD.md 指导用户如何验证源码与发布哈希清单的一致性
  • 隐私评估文档:独立的 privacy-assessment.md 坦诚披露已知隐私局限

快速上手

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 使用 Xcode 打开
open bitchat.xcodeproj

# macOS Debug 构建(无需签名)
xcodebuild -project bitchat.xcodeproj -scheme "bitchat (macOS)" \
-configuration Debug CODE_SIGNING_ALLOWED=NO build

# 运行完整 SwiftPM 测试套件
swift test

# iOS 模拟器测试
xcodebuild -project bitchat.xcodeproj -scheme "bitchat (iOS)" \
-sdk iphonesimulator \
-destination 'platform=iOS Simulator,name=iPhone 17' test

# 使用 just 命令
brew install just
just check
just run

11. 未来已来

当前挑战

物理限制:蓝牙 Mesh 的多跳传输依赖节点密度。在人口稀疏的郊区或野外,设备之间的距离可能远超蓝牙通信范围,Mesh 网络就会断裂。bitchat 不是”无限距离通信”,它的覆盖范围本质上受制于”你附近有多少人也在用 bitchat”。

元数据暴露:8 字节 Peer ID 派生自不轮换的密钥,公告以明文发布静态密钥和昵称。被动监听者可以枚举参与者并跨地点追踪设备,甚至通过公告中携带的邻居列表获取局部邻接图。这是白皮书坦诚承认的”设计中最薄弱的部分”。

内容审核:去中心化意味着没有中心节点来过滤违法内容。这在隐私保护上是绝对的优势。bitchat 目前的选择是”不处理”。

未来路线图

bitchat 的白皮书和架构文档列出了明确的改进方向:

  • Prekey 前向保密 —— 为信使邮件引入 prekey 机制,消除离线路径的前向保密缺失
  • 轮换空中身份 —— 纪元轮换 Peer ID,静态密钥在加密握手内披露,好友通过共享密钥派生标签相互识别
  • 非 Noise 包填充 —— 当前只有 Noise 帧有填充,其他包类型的负载长度可观测
  • 多跳信使路由 —— 基于相遇历史的多跳信使路由
  • 后量子就绪 —— 混合握手模式和 Kyber 集成计划
  • 多设备支持 —— 会话备份/恢复和组消息原语

未来的胡思乱想: 在解决了安全性和隐私性的问题之后 如果这东西中的某一个节点可以作为梯子 也许可以作为 一个不受任何政府监管的备用网络/隐秘网络。


结语:通信正在回归设备本身

过去十五年,我们习惯了把一切交给云端——消息存在服务器上,联系人存在服务器上,聊天记录存在服务器上。bitchat 说:不,通信可以只发生在设备之间。

bitchat 的爆发可能只是一个开始。随着蓝牙 6.0 规范的推进和 UWB(超宽带)技术在手机上的普及,”设备直连通信”的体验将会大幅提升。未来的 bitchat 可能不再局限于蓝牙,而是融合 Wi-Fi Aware、UWB 甚至卫星直连等多种无线技术,构建一个真正的多模态 Mesh 网络。

更长远地看,bitchat 代表的是一种趋势:通信正在从”云服务”回归”设备本身”。如果这种理念成为主流,改变的不仅是一个聊天工具,而是整个通信产业的架构逻辑。

It’s the side-groupchat. —— bitchat


参考链接


本文基于 bitchat 源码仓库及公开资料编写 · 2026 年 8 月

评论
分享