tralalananala-cloud/blink
GitHub: tralalananala-cloud/blink
Blink 是一款基于 libsignal 引擎的 Android 端到端加密通讯应用,无需电话号码或邮箱,采用后量子加密与 sealed sender 中继实现强匿名性与隐私保护。
Stars: 0 | Forks: 0
# Blink
Blink 使用 **libsignal**(Signal 官方引擎)对消息内容进行端到端加密:
X3DH + Double Ratchet + **PQXDH 后量子 (Kyber / ML-KEM)**。你的身份是一个
**仅存在于设备上**的密钥 —— 没有电话号码,没有电子邮件。消息通过
一个**无法读取**它们的最小化中继进行传输(sealed sender:连发送者是谁也看不到)。完整流程(handshake → 文本/媒体/语音消息 → 勾选标记 → 持久化 → 重新连接)
已在设备上**完成 E2E 验证**(arm64 手机 ↔ x86_64 模拟器),并通过实时中继传输。
## 是什么与不是什么
| 已交付并在设备上验证 | 明确推迟(v1 范围已冻结) |
|---|---|
| 真实的 **libsignal**:X3DH + Double Ratchet + **PQXDH/Kyber** 后量子 | **WebRTC** 音频/视频通话(代码已存在,未经物理测试) |
| Sealed sender(中继看不到发送者) | **MLS** 群组 |
| 盲目的 Cloudflare 中继 + auth challenge-response (Ed25519) | **桌面版** (Electron) —— 已搁置,无原生 libsignal |
| 静态存储 (Android):SQLite 包含**逐条消息加密的内容** (ChaCha20-Poly1305),密钥存于 Keystore;全文件 SQLCipher = 计划中 | **iOS**(需要 Apple 账户 + 调优 CocoaPods) |
| DID:key 身份 + BIP39 恢复短语 + 防 MITM 的安全码 | 基于 **Tor / I2P / Reticulum** 的传输 |
| 文本、图片、视频、文件、语音备忘录;编辑/删除;主题;应用锁定 + 单独会话密码 | F-Droid / 无 Google 推送 |
**设计核心:** 所有 UI 都与 `CryptoEngine` 接口 (`src/crypto/types.ts`) 通信 ——
没有任何屏幕直接接触加密原语。**在线上只有一个引擎**:
`libsignalEngine.ts`(原生,Android)。旧的纯 JS 引擎 (`signalEngine.ts`` +`signal/{x3dh,doubleRatchet}.ts`) 已在 2024-06-24 的审计中被**删除** —— 它是线上
第二个不兼容的格式。在 Web 端,`crypto/index.ts` 会返回一个诚实的 stub
(`UnavailableEngine`);桌面端已搁置。
## 架构
```
app/ # rute (expo-router, file-based)
_layout.tsx # fonturi + provideri + garda de securitate
index.tsx # poarta: onboarding vs tabs
onboarding/ # welcome → identitate → frază → biometrie
(tabs)/ # chats / contacts / vault / settings
chat/[id].tsx # conversația (prezentational + hooks de stare)
src/
crypto/ types.ts # CONTRACTUL motorului (UI vorbește DOAR cu el)
libsignalEngine.ts # libsignal REAL: PQXDH + Double Ratchet (nativ, Android)
signal/primitives.ts # wrappere @noble partajate (db/lock/relay)
index.ts # libsignal pe nativ, UnavailableEngine pe web
messaging/ relay.ts # client WS: connect/bundle/session/send/ack/edit
codec.ts outbox.ts # codec control + fiabilitate livrare (at-least-once)
storage/ db.ts # KV criptat (ChaCha20-Poly1305, cheie în SecureStore)
messages.ts # mesaje în SQLite, conținut criptat per-mesaj (write-through O(1)/eveniment)
secure.ts # SecureStore (Keystore) + fallback web
security/ lock.ts # app-lock + parolă per-conversație
identity/ did.ts # DID:key + frază recuperare BIP39 + safety number
state/ store.ts # zustand (slices) + persist criptat — ZERO chei private
i18n/ ro.ts en.ts # RO + EN
components/ # Card, GlowButton, MeshBackground, chat/*, ...
__tests__/ # crypto pur, identitate, relay wire, store, migrare, ...
```
中继:`~/cipher-relay/cf-worker` —— Cloudflare Worker + Durable Object (`Relay`,
WebSocket Hibernation,SQLite 存储)。Auth challenge-response,至少一次的离线队列,
FCM 推送。站点:`~/cipher-site` → blinkmessenger.vercel.app。
### 内置的安全决策
- 私钥 / 恢复短语**仅**通过 Android Keystore
(`expo-secure-store`, `WHEN_UNLOCKED_THIS_DEVICE_ONLY`)。绝不使用 AsyncStorage/纯文件。
- `state/store.ts` 仅保留**公开的**身份标识 + 对话;零密钥。
- **DID = `base32(sha256(idKey ‖ authPub))`** —— 加密承诺,在
建立会话 + 中继时进行验证(被攻破的中继无法替换密钥 → 首次接触时的 MITM 会在加密层面被阻挡,而不仅仅是通过安全码)。
- 没有遥测,没有分析,没有“回传数据”的 SDK。中继是**零日志**的。
- `expo-screen-capture`(防截图/录制)+ 后台内存清理。
## 威胁模型
与 [`SECURITY.md`](SECURITY.md) 保持一致(规范来源 —— 详情请阅读此文)。
**我们保护:**
- **消息内容** —— 通过 libsignal 进行 E2EE (X3DH + PQXDH + Double Ratchet)。中继无法读取。
- **无 PII 的身份** —— 设备上的密钥 (DID:key),无电话/电子邮件。通过 BIP39 恢复。
- **抗 MITM** —— 安全码(基于双方真实密钥的 SHA-256)+ 二维码验证 + 密钥更改警报 + DID↔密钥绑定。
- **Sealed sender** —— 中继看不到发送者是谁(仅看到接收者,用于路由)。
- **静态存储 (Android)** —— 密钥在 Keystore 中;消息在 SQLite 中包含逐条消息加密的内容 (ChaCha20-Poly1305)。全文件 SQLCipher = 计划中;索引时间戳保持明文。
**我们不保护(已知的限制):**
- **网络元数据** —— 中继 (Cloudflare) 可以看到 **IP、时间、流量体积**。Sealed sender
隐藏了发送者的 DID,而不是网络路径。Tor/I2P = 在 roadmap 中,尚未交付。
- **未验证联系人上的冒充** —— sealed envelope 在
外部层面不验证发送者(自声明 `sd`);真正的真实性来自内部(libsignal 消息仅在正确的会话下解密)+ 安全码。对于新联系人,
请验证安全码。
- **被攻破的设备** —— root/keylogger/malware 会击败任何通讯软件。
- **未经独立审计** —— 原语已被审计,但 Blink 的集成没有。
- **仅限 Android** —— 桌面端 (Electron) 已搁置;在其上,密钥将存储在未加密的 localStorage
中。安全的途径是 Android。
## 构建 (Android)
```
cd ~/cipher
export JAVA_HOME=~/Android/jdk-17.0.19+10 ANDROID_HOME=~/Android/Sdk
export PATH=~/.local/node20/bin:$JAVA_HOME/bin:$PATH
npx expo prebuild --clean
cd android && ./gradlew assembleRelease
# → android/app/build/outputs/apk/release/app-arm64-v8a-release.apk
adb install -r android/app/build/outputs/apk/release/app-arm64-v8a-release.apk
```
iOS:**无法**在 Linux 上编译(需要 Apple 账户 + EAS) —— 已推迟(参见范围表)。
### 测试与“可以安全构建”关卡
```
bash scripts/check.sh # Node 20 + tsc --noEmit + jest --ci + expo export web
```
在任何发布之前,该关卡必须是**绿色**的。
## v1 范围 (已冻结)
**v1 = Android 上的安全 1:1 聊天。** 仅此而已。明确推迟,位于接口之后,
不会阻塞 v1:WebRTC 通话,MLS 群组,桌面端,iOS,Tor/I2P/Reticulum 传输,
F-Droid/无 Google 推送。有关“完成定义”(Definition of Done),请参见 `HARDENING_PLAN.md`(第 5 阶段)。
许可证:**AGPL-3.0**。漏洞报告:私密的 GitHub Security Advisory(参见 `SECURITY.md`)。
标签:程序员工具, 自动化攻击