Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
Seal — 点对点、端到端加密聊天。没有收件箱。没有可恢复的账户。没有人窃听——包括我们自己。 | Kitploit
工具/GitHubGitHub/emn4tor/seal
加密/解密工具密码学隐私保护
GitHubemn4tor/seal

Seal

点对点、端到端加密聊天。没有收件箱。没有可恢复的账户。没有人窃听——包括我们自己。

查看仓库
9113天前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
Seal logo

Seal

点对点、端到端加密聊天。
无收件箱。无账户需要恢复。没有人在监听——包括我们。

github.com/Emn4tor/Seal

Rust: 1.97+ Tauri: 2.11.5 React: 19.2 Platforms: macOS, Linux, Windows Encryption: Olm / Megolm Server-side message storage: none

GitHub stars GitHub forks GitHub issues GitHub last commit GitHub repo size

Contributors Total commits

消息通过 libp2p 在节点之间直接传输,并在离开你的设备之前使用 Signal 风格的 Olm/Megolm 协议(通过 vodozemac)加密。唯一涉及的服务器是一个小型目录,帮助节点找到彼此的当前地址。它永远看不到消息内容,而且可以用一条命令清除。

有关实际防护的内容以及方式,请参阅 docs/THREAT_MODEL.md 和 docs/SECURITY.md。

Contents

  • 截图
  • 功能特性
  • 工作原理
  • 项目结构
  • 1. 前置要求
  • 2. 构建
  • 3. 以开发模式运行
  • 4. 测试
  • 5. 后端(目录服务器)设置
  • 6. 使用应用

截图

首次运行 —— 只需选择一个名称;无需其他设置。

Seal 的首次运行界面:加密模型说明旁边是显示名称表单,并带有一个登录时启动开关



会话 —— 群组栏、联系人列表和端到端加密聊天面板。

Seal 中的直接消息会话,显示群组栏、联系人列表和端到端加密聊天面板



设置 —— 麦克风灵敏度、按键通话、登录时启动、网络可达性。

Seal 的设置面板:麦克风灵敏度、按键通话、登录时启动和网络可达性

功能特性

  • 始终端到端加密 —— 每条消息在离开你的设备之前,都会使用 Olm(1:1) 或 Megolm(群组)进行密封,采用 vodozemac 的双棘轮(Double-Ratchet)式方案: 每条消息都有自己独立的密钥。
  • 永远没有收件箱 —— 消息通过点对点直接连接 (libp2p:QUIC/TCP + Noise,支持中继和 NAT 打洞)传输。如果接收方离线,消息会在本地等待并重试——绝不会排队存储在任何其他人的基础设施上。
  • 目录,而非数据库 —— 唯一涉及的服务器 (crates/directory-server)仅将用户 ID 映射到当前网络地址, 除此之外不做任何事情。它在结构上无法读取消息内容: 其 Cargo.toml 甚至不依赖任何知道如何读取消息内容的 crate。
  • 一台设备,多个账户 —— 完全独立的身份(密钥、 联系人、消息),无需重启即可切换。
  • 支持真实成员变更的群组 —— 每个群组都有文本和语音频道; 移除某人会轮换群组密钥,使其无法读取此后发送的任何内容。
  • 内置语音 —— 通过系统级快捷键进行按键通话(适用于任何应用,而不仅仅是 Seal),可调节麦克风灵敏度,并可选变声器。
  • 无元数据的附件 —— 图片在发送前会剥离 EXIF 数据(GPS 位置、 相机/设备信息),默认开启。
  • 真正的紧急按钮 —— 设置 → 数据与隐私可立即且不可逆地删除本设备上的所有密钥、联系人和消息,而不会对你联系过的任何人产生任何影响。
  • 如果需要,登录时启动 —— 默认开启,在设置中一键切换。
  • 一套代码库,三个平台 —— 通过 Tauri 在 macOS、Windows 和 Linux 上提供原生窗口。

工作原理

这个应用中有两种身份,它们被刻意分开:

  • 你的聊天身份 是 vodozemac 在你首次打开应用时在本地生成的 Ed25519/Curve25519 密钥对(identity::Identity)。你的公开“用户 ID”就是该密钥的指纹(wire_proto::user_id_from_ed25519)。任何服务器都无法签发或吊销它,因为它的创建过程不涉及任何服务器。
  • 你的网络身份 是一个单独的 libp2p 密钥对(PeerId),仅用于传输层。它可以在重启之间变化,而完全不影响你的聊天身份;两者仅通过你自行签名的在线状态记录绑定在一起。

找到某人并真正与他们交谈是两个不同的步骤:``` ┌────────────────────────┐ │ directory server │ │ (axum + one SQLite │ │ file: users, │ │ presence, group │ │ rosters. Never │ │ message content.) │ └─────────┬───────────────┘ 1. "where is bob │ 2. "here's my current right now?" │ address" (signed, │ expires in minutes) ┌─────────┴───────────────┐ ▼ ▼ ┌───────┐ 3. direct libp2p ┌───────┐ │ alice │◄──── connection ────►│ bob │ └───────┘ (Noise + Olm/ └───────┘ Megolm encrypted)

root@kitploit:~
1. Alice 通过 Bob 的用户 ID 在目录中查找他。这会返回他的
   公钥以及他最后通告的网络地址。这就是目录所持有的全部内容:
   公钥、显示名称、组成员列表,
   以及短期有效的地址通告
   (`crates/directory-server`)。
2. Alice 直接通过 libp2p(QUIC 或 TCP+Noise,带中继 +
   NAT 打洞,用于 NAT 后的对等方;参见 `crates/net`)呼叫 Bob。目录从
   此刻起完全不再参与。
3. 实际消息会使用 **Olm**(用于 1:1 聊天)或
   **Megolm**(用于群组,`crates/crypto-session`),这是一种 Double-Ratchet 风格
   方案,每条消息在放到该 libp2p 连接之前
   都有自己的密钥。没有服务器端收件箱:如果 Bob 离线,
   消息会在本地等待并重试,而不是存储在任何其他人的
   基础设施上。

以上所有内容均由 `crates/core` 的 `AppService` 编排,它
是 Tauri 应用的 Rust 后端(`apps/desktop/src-tauri`)实际调用的对象;
UI 从不直接与网络通信。

## 项目布局```
crates/
  wire-proto        shared signed-request types for the directory API
  identity          vodozemac identity, OS-keychain key management
  storage           local encrypted store (contacts, messages, groups)
  net               libp2p transport + directory HTTP client
  crypto-session    Olm (1:1) / Megolm (group) session management
  core              orchestrates the above into `AppService` / `ChatNode`
  directory-server  the one server component (axum + SQLite)
apps/desktop         the Tauri + React app
scripts/             build + backend-deployment scripts (§2, §5)

1. 前置要求

你在每个平台上都需要 Rust 和 Node.js,此外还需要 Tauri 用于构建原生窗口的、特定于平台的 工具链。storage 和 directory-server 还会从源码捆绑编译 SQLite,这需要一个普通的 C 编译器(本项目中 任何地方都不需要 OpenSSL 或其他原生加密库)。

所有平台通用:

  • Rust(稳定版渠道;通过 rustup 安装,不要用操作系统的包管理器)
  • Node.js 20+ 和 npm
macOS```sh xcode-select --install ``` 就这样。Xcode 命令行工具既提供了 C 编译器,也提供了 Tauri 的 macOS 后端(基于 WKWebView)所需的框架。
Linux

安装一个 C 编译器、pkg-config 以及 Tauri 的 Linux 后端所链接的 WebKitGTK/AppIndicator 开发 包。

Debian/Ubuntu:```sh sudo apt update sudo apt install libwebkit2gtk-4.1-dev build-essential curl wget file
libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev pkg-config

root@kitploit:~
Fedora:```sh
sudo dnf install webkit2gtk4.1-devel openssl-devel curl wget file \
  libappindicator-gtk3-devel librsvg2-devel pkgconf-pkg-config
sudo dnf group install "C Development Tools and Libraries"

架构:```sh sudo pacman -S --needed webkit2gtk-4.1 base-devel curl wget file openssl
appmenu-gtk-module libappindicator-gtk3 librsvg pkgconf

root@kitploit:~
(软件包名称会随 Tauri 版本变化:如果构建时因缺少
`.pc` 文件而失败,请查阅
[当前 Tauri Linux 先决条件](https://v2.tauri.app/start/prerequisites/)
以获取适用于你的发行版的信息。)

</details>

<details>
<summary><strong>Windows</strong></summary>

1. 安装 **Microsoft C++ Build Tools**(Visual Studio Installer →
   “Desktop development with C++” 工作负载),Tauri 的原生
   Shell 和编译捆绑的 SQLite 都需要它。
2. 安装 **MSVC** Rust 工具链:`rustup default stable-msvc`。
3. **WebView2**:已存在于 Windows 11 和大多数最新的 Windows 10
   安装中;如果没有,Tauri 构建时会提示你安装
   Evergreen 运行时。

</details>

---

## 2. 构建

从仓库根目录:```sh
# Rust workspace (backend crates + the directory server)
cargo build --workspace --release

# Frontend + the actual desktop app bundle (installer/.app/.exe)
cd apps/desktop
npm install
npm run tauri build

npm run tauri build 会在仓库根目录下的 中生成一个平台原生的安装程序(这是一个 Cargo 工作区,因此所有 crate,包括 Tauri 应用,共享同一个顶层 目录)。未配置交叉编译(例如从 macOS 构建 Windows 安装程序):请在各个目标平台上构建,或者如果你想要由 CI 构建的发布版本,请使用 Tauri 的 GitHub Actions 工作流。

下载工具
target/release/bundle/
target/

或者使用脚本

scripts/ 为每个平台/输出提供一个构建脚本,每个脚本都可独立运行,并且都经过验证确实能生成可用的工件:

脚本产物
scripts/build-mac-dmg.shmacOS .dmg 安装程序
scripts/build-mac-app.sh原始 macOS .app 应用包,无安装程序
scripts/build-linux.shLinux .AppImage + .deb
scripts/build-windows.ps1Windows .msi + .exe (NSIS)

每个脚本都只是用正确的标志和平台检查来包装 npm run tauri build --bundles <...>;如果你想使用不同的打包组合,可以自己运行原始命令(从 apps/desktop 目录执行 npx tauri build --help)。

scripts/release.sh vX.Y.Z 会在所有需要更新版本的地方更新版本号,并给提交打上标签——参见 docs/RELEASING.md。可在 macOS 和 Linux 上运行;不会提交或推送。

内置你自己的“Seal”网络

服务器选择界面(§3)始终显示三个选项:Seal(你自己的官方网络)、Custom server,以及底部的一个小链接 Local test server。在你于 构建 时内置一个 URL 之前,“Seal” 处于禁用状态(灰显,并显示“此构建中尚未配置”)。```sh SEAL_DEFAULT_DIRECTORY_URL=https://directory.example.com npm run tauri build

root@kitploit:~
一旦你搭好了自己的服务器(§5)并将一个真实域名指向它,设置此项并重新构建:此后你分发的每个副本都会将“Seal”显示为一个真实、可选的选项,使用该 URL,而无需改动任何其他代码。对于普通/开发构建则保持未设置状态:本仓库并未托管任何官方服务器,因此“Seal”保持禁用,用户会回退到自定义服务器或本地服务器,而不是让应用静默指向一个实际上并未运行任何内容的占位域名。

---

## 3. 以开发模式运行```sh
cd apps/desktop
npm install
npm run tauri dev

这将启动 Vite 开发服务器,以调试模式编译 Rust 后端, 并打开一个原生窗口,前端支持热重载。首次构建会编译整棵依赖树,需要几分钟;之后的运行会很快。

选择服务器(首次运行)

首次启动时,Seal 会询问使用哪个目录服务器,按以下顺序:

  • Seal:官方网络,如果当前构建内置了该网络(见 §2)。在尚未内置之前保持禁用;本仓库未预置指向 占位域名的配置。
  • 自定义服务器:任何人的服务器,包括你自己的(§5)。
  • 本地测试服务器:底部一个较小的、刻意弱化的链接。 启动应用自带的嵌入式服务器(绑定 127.0.0.1:47100/47101,数据存放在操作系统应用数据目录下), 适合体验 Seal 或在单台机器上测试实例,并非真正的部署。 如果第二个实例发现这些端口已被占用,它会直接 复用第一个实例的服务器,而不是再启动一个新实例, 这正是两台实例在同一台机器上能够互相发现的原因。若未配置 “Seal” 且你未选择其他项,则会自动选中此项。

该选择会被保存(server.json 与应用其他本地数据放在一起),并在之后的每次启动时静默复用;可通过设置 → 目录服务器进行更改,更改会在下次启动应用时生效,而不是尝试热切换正在运行的连接。对于脚本化/开发用途,可通过环境变量完全跳过该提示:```sh P2P_CHAT_DIRECTORY_URL=https://directory.example.com npm run tauri dev

root@kitploit:~
### 在本地运行两个实例(用于实际测试消息传递)

每个实例都需要自己的身份。Seal 原生支持多个账户(此设备上的设置 → 账户),但对于一台机器上的两个*独立进程*,`P2P_CHAT_PROFILE` 是更快的途径:它会非交互式地自动创建(首次)或自动恢复(之后每次)一个具有该名称的账户,完全跳过账户选择器:```sh
# terminal 1
P2P_CHAT_PROFILE=alice npm run tauri dev

# terminal 2
P2P_CHAT_PROFILE=bob npm run tauri dev

服务器选择(server.json)和账户列表(accounts.json)在同一台机器的所有进程间共享,而不是按配置文件区分。你首次启动的实例会选定服务器,之后每个配置文件(包括这里的 bob)都会静默复用该服务器。两个窗口最终都连接到同一个内嵌目录服务器,因此你们可以通过 ID 将彼此添加为联系人,并在两者之间发送消息。

Vite 的开发服务器需要一个真实且固定的端口供 Tauri 的 webview 指向,这通常意味着同一时间只能运行一个 npm run tauri dev——第二个会发现端口 1420 已被占用而直接失败。npm run tauri 实际上是一个小型包装脚本(apps/desktop/scripts/tauri.mjs),它会为第一个之后的每个实例选择下一个可用端口(1421、1422、……)并自动传递进去,所以在两个终端中运行上述两条命令即可正常工作,你不需要做任何额外操作。它只改变 dev 的行为——npm run tauri build 以及其他所有命令都会直接透传给真实的 CLI。

针对真实构建进行测试(非开发模式)```sh

./scripts/run-two-mac-instances.sh # profiles: alice, bob ./scripts/run-two-mac-instances.sh carol dave

root@kitploit:~
与上述想法相同,但会启动实际构建的应用(`build-mac-app.sh` /
`build-mac-dmg.sh` 的输出,或安装在 `/Applications` 中的副本)两次
分别使用不同的 `P2P_CHAT_PROFILE`,而不是 `npm run tauri dev`,更接近
真实用户运行的情况。会打印 PID 以及如何停止两者。

### 调试

- **Rust 日志**:启动前设置 `RUST_LOG`,例如
  `RUST_LOG=debug npm run tauri dev`(或 `RUST_LOG=p2p_core=debug,net=debug`
  来缩小范围)。记录的字段仅限元数据(对等节点/群组/用户
  ID、错误类型);参见 [`docs/SECURITY.md`](https://github.com/emn4tor/seal/blob/HEAD/docs/SECURITY.md)
  了解为何可以放心保留详细日志。
- **前端**:开发窗口是真实的 webview;右键单击 → 检查
  元素(或打开开发者工具)即可像普通浏览器一样操作。
- **后端 crate 的隔离测试**:每个 crate 都有自己的测试套件,你可以
  在完全不接触 UI 的情况下运行和迭代;参见 §4。
- **独立的目录服务器**,而非内置服务器:参见 §5。

---

## 4. 测试```sh
# everything
cargo test --workspace

# one crate, e.g. the full backend-to-backend flow a Tauri command would trigger
cargo test -p p2p-core --test app_service

# lint + format check (what CI runs)
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings

# dependency vulnerability scan
cargo install cargo-audit --locked   # once
cargo audit

# frontend type-check + build
cd apps/desktop && npm run build

5. 后端(目录服务器)设置

这里实际是什么,先做个概述,因为很容易想复杂:一个 axum 进程,一个 SQLite 文件,三类记录(公钥、短期在线状态公告、群组成员名单),所有写入均由调用者自己的身份密钥签名。它绝不会出现在消息的传输路径上。关于为什么这在结构上(而非仅仅是策略上)成立,请参阅 docs/THREAT_MODEL.md:directory-server 的 Cargo.toml 甚至不依赖那些能读取消息内容的 crate。

最快路径:设置脚本```sh

sudo ./scripts/setup-backend.sh

root@kitploit:~
交互式,仅限 Linux + systemd(原因见脚本头部说明)。它会询问你使用的是哪个发行版系列(Debian/Ubuntu、Fedora/RHEL/Rocky/Alma、Arch/Manjaro 或 openSUSE),并根据 `/etc/os-release` 预先填好一个猜测值,因此通常只需按一次键确认;然后通过每个系列专用的函数安装该发行版的构建依赖。如果缺少 Rust,它会提议通过 `rustup` 安装;接着构建 release 二进制文件、创建专用系统用户、生成管理员令牌。它会询问你是希望它通过 [Caddy](https://caddyserver.com) 配置域名并自动启用 HTTPS(按发行版安装 Caddy 本身,如果某个发行版没有可用软件包,则回退到 Caddy 官方静态二进制文件),还是仅绑定回环地址/明文 HTTP,以便你自己作为前端处理,然后写入并启用 systemd 服务。可安全地重复运行。
下面的内容就是它实际所做的;如果你更愿意手动操作,或在运行前想了解清楚,可以往下看。

### macOS:一个快速的局域网测试服务器```sh
./scripts/run-mac-test-server.sh

不用于正式托管:用于在同一网络的两台设备间测试应用(例如你的 Mac 加另一台机器, 或两个人在同一 Wi-Fi 下),而无需设置域名、TLS 或 systemd(macOS 上本来就没 有 systemd)。它会构建 release 二进制文件,生成一个管理员令牌(在后续运行 中复用),将公共 API 绑定到所有接口,并打印要使用的 URL:你 Mac 的实际局域网 IP(通过 ipconfig getifaddr 获取),而不仅仅是 127.0.0.1,这样其他设备 也能访问。管理员端口仅监听在 loopback 上。 在前台运行;按 Ctrl-C 停止。 数据存放在 ~/.seal-test-server 下。

快速本地运行```sh

DIRECTORY_DB_PATH=/var/lib/seal-directory/directory.sqlite3
DIRECTORY_PUBLIC_ADDR=0.0.0.0:8080
DIRECTORY_ADMIN_ADDR=127.0.0.1:8090
DIRECTORY_ADMIN_TOKEN=$(openssl rand -hex 32)
cargo run --release -p directory-server --bin directory-server

root@kitploit:~
| 变量 | 必填 | 含义 |
|---|---|---|
| `DIRECTORY_DB_PATH` | 否(默认 `directory.sqlite3`,当前工作目录) | 单个 SQLite 文件所在位置。父目录必须存在。 |
| `DIRECTORY_PUBLIC_ADDR` | 否(默认 `0.0.0.0:8080`) | 应用与之通信的会合 API。可以公开暴露。 |
| `DIRECTORY_ADMIN_ADDR` | 否(默认 `127.0.0.1:8090`) | 清除端点。请勿将其暴露在公共互联网上;见下文。 |
| `DIRECTORY_ADMIN_TOKEN` | **是** | 管理 API 的 Bearer 令牌。没有它,进程将拒绝启动。使用 `openssl rand -hex 32` 或类似方式生成;不要在别处复用。 |

进程在启动时会记录它绑定的地址,如果
`DIRECTORY_ADMIN_ADDR` 不是回环地址,就会发出强烈警告。

### 将应用指向它

有三种方式,按你通常会采用的顺序:

1. **首次运行屏幕**:选择“自定义服务器”并输入 URL。参见 §3。
2. **设置 → 目录服务器**:之后可以更改;下次
   重启时生效。
3. **`P2P_CHAT_DIRECTORY_URL`**,在启动前设置:完全跳过询问
   并覆盖已保存的任何内容,对开发/脚本化运行很有用:   ```sh
   P2P_CHAT_DIRECTORY_URL=https://directory.example.com npm run tauri dev

所有想要相互找到对方的人都需要指向同一个目录实例;这正是他们最初相互查找的方式。

作为真实服务(systemd)运行

显示 systemd unit 和说明```ini # /etc/systemd/system/seal-directory.service [Unit] Description=Seal directory server After=network.target

[Service] Type=simple User=seal-directory Group=seal-directory Environment=DIRECTORY_DB_PATH=/var/lib/seal-directory/directory.sqlite3 Environment=DIRECTORY_PUBLIC_ADDR=127.0.0.1:8080 Environment=DIRECTORY_ADMIN_ADDR=127.0.0.1:8090 EnvironmentFile=/etc/seal-directory/admin-token.env ; DIRECTORY_ADMIN_TOKEN=... ExecStart=/usr/local/bin/directory-server Restart=on-failure

Sandboxing: this process needs almost nothing

ProtectSystem=strict ProtectHome=true PrivateTmp=true NoNewPrivileges=true ReadWritePaths=/var/lib/seal-directory

[Install] WantedBy=multi-user.target

root@kitploit:~
Notes:

- `DIRECTORY_PUBLIC_ADDR` 此处特意绑定到 **loopback**;请在前面放置反向代理以处理 TLS(见下文),而不是直接将 axum 暴露到互联网。
- 首先创建 `seal-directory` 系统用户/组和
  `/var/lib/seal-directory`(`useradd --system --no-create-home
  seal-directory && install -d -o seal-directory -g seal-directory
  /var/lib/seal-directory`),并将构建好的 `directory-server` 二进制文件
  (来自 `target/release/`)复制到 `/usr/local/bin/`。
- 将管理员令牌放在仅 root 可读的 `EnvironmentFile` 中,而不是直接
  放在 unit 文件中(unit 文件通常对所有人可读)。

</details>

### 通过反向代理使用 TLS

<details>
<summary>显示 Caddy / nginx 配置</summary>

[Caddy](https://caddyserver.com) 以最少的配置即可获得自动 HTTPS:```
# /etc/caddy/Caddyfile
directory.example.com {
    reverse_proxy 127.0.0.1:8080
}

caddy run(或 systemctl enable --now caddy)会自行处理证书的签发/续期。如果你更愿意使用 nginx,可以在 nginx 上终止 TLS,然后配置 proxy_pass http://127.0.0.1:8080;,因为从代理的角度来看,该应用只需要纯 HTTP。

防火墙方面:只有公共端口需要能从外部访问(上述示例中的 8080,通过代理以 443 为前端)。管理端口绝不应从外部访问;当您需要远程执行清理时,可通过 SSH 端口转发(ssh -L 8090:127.0.0.1:8090 your-server)访问它。

清理它```sh

cargo run --release -p directory-server --bin directory-admin --
--admin-url http://127.0.0.1:8090 --token "$DIRECTORY_ADMIN_TOKEN" purge

root@kitploit:~
此操作会删除 SQLite 文件并重新创建一个空 schema:不执行任何 `DELETE`
语句,也不会留下部分状态。无需提前通知任何人即可安全运行:
其中的每条记录都是各客户端本地已持有的数据缓存
(即它们自己的注册信息、在线状态,以及它们所属任何群组的
成员名单),因此客户端只需在下次操作后的片刻内重新填充它。
这个数据库刻意不设置备份策略;至于为何保留备份
会破坏其全部意义,请参阅 [`docs/SECURITY.md`](https://github.com/emn4tor/seal/blob/HEAD/docs/SECURITY.md)
中的说明。

---

## 6. 使用应用

1. **首次启动,第一个问题**:要使用哪个目录服务器(§3)。
   默认值就是你正在运行的构建版本内置的内容(本地
   测试服务器,除非构建者配置了官方服务器);选择
   “Custom server”即可指向由你或你信任的人托管的服务器。
2. **选择一个显示名称。** 这会在你的设备上生成一个密钥对
   (无需记忆任何内容,丢失后也无法恢复:这是有意为之),
   并引导你阅读应用内关于加密实际工作原理的简短说明。
   可随时从 Settings 中重新查看该说明。之后的每次
   启动都会直接回到应用,不再提示;此流程每个账户只会
   出现一次。可通过本设备的 Settings →
   Accounts(完全独立的身份),并在不重启的情况下切换账户。
3. **添加联系人**:点击“Direct messages”旁边的 **+**,输入对方的
   ID(可在*对方*的 Settings → My Identity 中找到)。设计上
   没有可供浏览的目录;你联系对方的方式与分享电话号码相同。
4. **给他们发消息**:从列表中选择对方的名字并输入内容。发给某人的
   第一条消息会自动建立加密会话。
5. **创建群组**:点击图标栏上的 **+**,为其命名,然后用同样的方式
   按 ID 邀请成员。移除某人会轮换群组密钥,使其无法读取之后
   发送的任何内容。
6. **删除所有内容**:Settings → Data & Privacy。此操作即时生效、
   仅限本地且不可逆转:它会销毁*此设备*上的密钥、联系人和
   历史记录,并且不会对你联系过的任何人产生任何影响。