SecurityRonin/signal-desktop-forensic
GitHub: SecurityRonin/signal-desktop-forensic
一款 Rust 编写的 Signal Desktop 取证解析器,通过 OS Safe Storage 密钥解密 SQLCipher 数据库并提取对话、消息、联系人和附件等类型化记录。
Stars: 0 | Forks: 0
# signal-desktop-forensic
[](https://crates.io/crates/signal-desktop-core)
[](https://crates.io/crates/signal-desktop-forensic)
[](https://securityronin.github.io/signal-desktop-forensic/)
[](https://www.rust-lang.org)
[](LICENSE)
[](https://github.com/sponsors/h4x0r)
[](https://github.com/SecurityRonin/signal-desktop-forensic/actions/workflows/ci.yml)
[](https://github.com/rust-secure-code/safety-dance/)
[](https://rustsec.org/)
**解密 Signal Desktop 配置文件并读取其消息 —— 为您处理密钥恢复、
SQLCipher 以及 Signal 的 schema。**
Signal Desktop 将每条消息、对话、联系人和附件记录
保存在一个 **SQLCipher 加密**的数据库中。密钥并非明文:它
被 OS Safe Storage 封装在 `config.json` 中。此 crate 走完整个
链路并为您提供带有类型的记录。
```
use signal_desktop_core::{config::SignalConfig, keys::unwrap_sqlcipher_key, store::SignalStore};
use chromium_safestorage_core::RecoveredKey;
# fn demo(profile: &std::path::Path, os_key: RecoveredKey) -> signal_desktop_core::Result<()> {
// 1. Parse config.json and unwrap the SQLCipher key with the OS Safe Storage key.
let config = SignalConfig::from_profile(profile)?;
let sqlcipher_key = unwrap_sqlcipher_key(&os_key, &config)?;
// 2. Open the encrypted database and read typed records + a timeline.
let store = SignalStore::open_profile(profile, &sqlcipher_key)?;
for msg in store.messages()? {
println!("{} [{}] {}", msg.sent_at.unwrap_or(0), msg.direction, msg.body.unwrap_or_default());
}
for entry in store.timeline()? {
println!("{:?}", entry);
}
# Ok(())
# }
```
**错误或缺失的密钥会明确报错** —— 返回类型化的 `SignalError`,绝不会返回空行,
也绝不会伪造明文。所有加密操作均经过审计:使用 RustCrypto AES-128-CBC
进行 `encryptedKey` 解封,使用参考的 SQLCipher 库处理数据库。
## 两个 crate
| Crate | 角色 |
|---|---|
| `signal-desktop-core` | 读取器:恢复密钥,打开 DB,暴露 `Conversation` / `Message` / `Contact` / `Attachment` 以及 `TimelineEntry` 流。无发现。 |
| `signal-desktop-forensic` | 分析器:将记录评级为规范化的 `forensicnomicon` 发现(采用 consistent-with(与……一致)表述语言,绝非直接定论)。 |
## Pipeline
```
OS Safe Storage key ─▶ decrypt config.json encryptedKey (v10, AES-128-CBC)
─▶ SQLCipher raw key (64 hex = 32 bytes)
─▶ PRAGMA key ─▶ sql/db.sqlite
─▶ messages · conversations · contacts · attachments · timeline
```
OS Safe Storage 密钥本身由
[`chromium-safestorage`](https://github.com/SecurityRonin/chromium-safestorage)
恢复(macOS Keychain / Windows DPAPI / Linux libsecret);此 crate 将
`RecoveredKey` 作为输入。
## 信任,但须验证
- **输入经过模糊测试。** 每个解析的结构对应一个 `cargo-fuzz` 目标 ——
包括 `config.json` 解码、v10 密钥解封路径,以及每条消息的 JSON ——
每次推送时进行冒烟测试,并按计划进行限时测试。不变式:遇到任意字节绝不 panic。
- **通过 lint 实现 panic-free。** 在生产环境中设为 `unsafe_code = forbid`,`unwrap_used`/`expect_used =
deny`,通过 `safe-read` 进行有界读取。
- **基于真实应用程序的字节进行验证。** `config.json` 的 schema 和
`encryptedKey` 的 v10 格式已对照真实的宿主机 Signal profile 进行了确认;
记录解析在 Signal 文档记录的 schema 中铸造的 SQLCipher DB 上进行了验证。有关诚实的分级,请参阅 [`docs/validation.md`](docs/validation.md)。
[隐私政策](https://securityronin.github.io/signal-desktop-forensic/privacy/) · [服务条款](https://securityronin.github.io/signal-desktop-forensic/terms/) · © 2026 Security Ronin Ltd
标签:HTTP工具, Rust, Signal, SQLCipher, 可视化界面, 安全助手, 数字取证, 数据解密, 网络流量审计, 自动化脚本