SecurityRonin/chromium-safestorage
GitHub: SecurityRonin/chromium-safestorage
跨平台恢复并解密 Chromium 浏览器 Safe Storage 密钥的 Rust 取证工具,支持 macOS、Windows 和 Linux。
Stars: 0 | Forks: 0
# chromium-safestorage
[](https://crates.io/crates/chromium-safestorage-core)
[](https://crates.io/crates/chromium-safestorage-forensic)
[](https://docs.rs/chromium-safestorage-core)
[](https://www.rust-lang.org)
[](LICENSE)
[](https://github.com/sponsors/h4x0r)
[](https://github.com/SecurityRonin/chromium-safestorage/actions/workflows/ci.yml)
[](https://github.com/rust-secure-code/safety-dance)
[](deny.toml)
**恢复 Chromium 的“Safe Storage”密钥——这把万能密钥可解锁每一个 Chrome / Edge / Brave 的 cookie、保存的登录凭据及 messenger 数据库——从获取的磁盘中,根据源 OS 进行分发提取。**
一把密钥保护所有数据。在 macOS 上,它存在于登录 Keychain 中;在 Windows 上,它被 DPAPI 包装在 `Local State` 内;在 Linux 上,它来自密钥环(`v11`)或硬编码的密码(`v10`)。`chromium-safestorage` 在这三个平台上都能恢复它,并交给你一个 `RecoveredKey`,可以直接解密从 `Cookies` 数据库中提取的 `v10` cookie 值——**仅使用经过审计的 RustCrypto**,并且在输入无法解锁时**抛出明确的错误,绝不伪造密钥**。
```
use chromium_safestorage_core::{recover_key, KeySource};
// macOS: read `Chrome Safe Storage` from an acquired login.keychain-db …
let keychain = std::fs::read("login.keychain-db")?;
let key = recover_key(KeySource::MacOs {
keychain: &keychain,
login_password: b"login-password",
service: "Chrome Safe Storage",
})?;
// … then decrypt a v10 cookie value straight from the Cookies DB.
let plaintext = key.decrypt_cookie(encrypted_value)?;
# Ok::<(), chromium_safestorage_core::SafeStorageError>(())
```
## 恢复内容
| OS | 密钥来源 | 密钥派生 | 加密算法 | 密钥 |
|---|---|---|---|---|
| **macOS** | ` Safe Storage` Keychain 通用密码(通过 [`keychain-core`] 离线获取) | PBKDF2-HMAC-SHA1,盐值 `saltysalt`,1003 轮 | AES-128-CBC | 16 B |
| **Windows** | `Local State` `os_crypt.encrypted_key`,DPAPI 解包(通过 [`dpapi-core`]) | DPAPI | AES-256-GCM (`v10`) | 32 B |
| **Linux `v11`** | gnome-keyring / kwallet Secret Service 密钥 | PBKDF2-HMAC-SHA1,1 轮 | AES-128-CBC | 16 B |
| **Linux `v10`** | 硬编码的 `peanuts` 密码(无需密钥) | PBKDF2-HMAC-SHA1,1 轮 | AES-128-CBC | 16 B |
恢复的 [`RecoveredKey`] 标记了其加密体系,因此 `decrypt_cookie` 会自动为你选择 AES-128-CBC 或 AES-256-GCM——你不会应用错误的加密算法。较新的 Chromium 会在明文前添加一个 32 字节的 `SHA-256(host_key)` 域名哈希;`strip_domain_hash` 会在针对 cookie 的主机**验证通过后**将其移除。
## CLI — `safestore4n6`
```
$ safestore4n6 macos --keychain login.keychain-db --password 'hunter2' \
--service 'Chrome Safe Storage' --cookie cookie.bin --host accounts.google.com
[macos] key=cf5505107fba7a67db54d90d9137187b
cookie=SID=...
$ safestore4n6 windows --local-state 'Local State' --master-key 0x9828… --cookie cookie.bin
$ safestore4n6 linux-v10 --cookie cookie.bin --host example.com
```
锁定的 keychain 或缺失的 DPAPI 主密钥会以非零状态退出,并显示一条 *存在但已锁定* 的消息——绝不返回猜测的密钥。
## 两个 crate
- **`chromium-safestorage-core`** ——基于 OS 分发的恢复 + cookie 解密库(`recover_key`、`RecoveredKey`、`derive_*`)。作为 `chromium_safestorage_core` 导入。
- **`chromium-safestorage-forensic`** ——构建于其上的 `safestore4n6` CLI。
## 信任,但要验证
- **模糊测试** ——libFuzzer 目标驱动 cookie 解密和 `Local State` 边界处理任意字节流;不变式是没有任何输入会导致 panic。
- **通过 lint 保证无 panic** ——`#![forbid(unsafe_code)]`,生产环境禁止使用 `clippy::unwrap_used` / `expect_used`;错误的密钥、糟糕的填充或失败的 GCM 标签都会返回一个类型化的 `SafeStorageError`。
- **经过审计的加密,没有伪造** ——PBKDF2 / AES-CBC / AES-GCM 来自 RustCrypto crate 和两个客户端读取器;没有手动实现的加密原语,也没有占位符会返回看似合理但错误的字节。
- **通过独立的预言机(Oracle)进行验证** ——参见 [`docs/validation.md`](docs/validation.md):一个 Apple 生成的 keychain 夹具,由 Python 的 `cryptography` 库生成的 Chromium `v10` cookie 密文,RFC 6070 PBKDF2 向量,以及已发布的 Linux `v10` 密钥——此外还有针对 macOS 上真实 Chrome 的实时闭环测试。
## 参考
Chromium `components/os_crypt/sync/os_crypt_mac.mm` / `os_crypt_linux.cc` / `os_crypt_win.cc` (`kSalt = "saltysalt"`, macOS `kDerivedKeyIterations = 1003`, Linux fallback password `"peanuts"`, `v10`/`v11`/`v20` prefixes)。
[隐私政策](https://securityronin.github.io/chromium-safestorage/privacy/) · [服务条款](https://securityronin.github.io/chromium-safestorage/terms/) · © 2026 Security Ronin Ltd
标签:Chromium, Rust, 凭证提取, 可视化界面, 密码学解密, 数字取证, 网络流量审计, 自动化脚本, 通知系统