SecurityRonin/keychain-forensic

GitHub: SecurityRonin/keychain-forensic

一个纯 Rust 实现的 macOS Keychain 离线取证库,仅需账户密码即可从 login.keychain-db 中恢复和解密存储的机密。

Stars: 0 | Forks: 0

# keychain-forensic [![Crates.io](https://img.shields.io/crates/v/keychain-core.svg)](https://crates.io/crates/keychain-core) [![Docs.rs](https://docs.rs/keychain-core/badge.svg)](https://docs.rs/keychain-core) [![Rust 1.85+](https://img.shields.io/badge/rust-1.85%2B-blue.svg)](https://www.rust-lang.org) [![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE) [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/SecurityRonin/keychain-forensic/actions/workflows/ci.yml) [![unsafe forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance/) [![Sponsor](https://img.shields.io/badge/sponsor-%E2%9D%A4-db61a2.svg)](https://github.com/sponsors/h4x0r) **使用纯 Rust 离线解密 macOS `login.keychain-db` —— 只需提供账户登录密码,即可从获取的磁盘镜像中恢复通用密码(generic-password)机密,包括 Chromium 的 `Safe Storage` 密钥。** `login.keychain-db` 是 macOS 上类似 Windows DPAPI 的机制:账户密码 保护着一串密钥,而这些密钥随后会加密所有存储的机密。恢复 Chrome/Edge/Brave 的 **Safe Storage** 密钥后,你就可以在挂载的、获取的镜像上解密该浏览器保存的 cookie 和登录凭证。`keychain-core` 完全在离线状态下完成整个 解锁链 —— 无需实时目标,无需 Keychain Access,也无需调用 macOS API —— 仅从字节缓冲区即可开始。 ## 快速开始 ``` [dependencies] keychain-core = "0.1" ``` ``` use keychain_core::Keychain; let bytes = std::fs::read("login.keychain-db")?; let kc = Keychain::open(&bytes)?; let unlocked = kc.unlock(b"login-password")?; // wrong pw -> KeychainError::Locked for s in unlocked.generic_secrets() { println!("{} / {} => {}", s.account, s.service, s.display()); } # Ok::<(), Box>(()) ``` 或者使用 `kc4n6` CLI(`keychain-forensic` 分析器): ``` $ kc4n6 login.keychain-db --password 'login-password' [SAFE-STORAGE] service=Chrome Safe Storage account=Chrome secret=hex:1a2b... [generic] service=MySecretService account=alice secret=S3cr3t-KC-Value! ``` ## 工作原理 整个解锁链均通过经过审计的 [RustCrypto](https://github.com/RustCrypto) crate 完成 —— 没有手工编写的数学运算: 1. `master = PBKDF2-HMAC-SHA1(password, DbBlob.salt, 1000, dkLen=24)`; 2. `DBKey = unpad(3DES-EDE3-CBC-decrypt(master, DbBlob.iv, ciphertext))`; 3. 每个记录密钥都使用 DBKey 从对称密钥表中通过 CMS 解包出来(固定魔数 IV,32 字节反转,第二次 3DES 传递); 4. 每个机密都通过 `3DES-CBC-decrypt(record_key, ssgp.iv, payload)` 解密。 错误或缺失的密码将无法通过 DBKey 填充检查,并会被报告为 `KeychainError::Locked` —— 存储处于*存在但已锁定*的状态,绝不会伪造 机密。在取证工具中,看似合理但错误的明文属于伪造的 证据,因此每一次失败都会以类型化的错误呈现。 ## 两个 crate - **`keychain-core`** —— 面向字节的读取器/解密器。每个入口点都 接收 `&[u8]` 并执行无 I/O 操作,因此同一套代码可以用于实时文件、从磁盘镜像中提取的文件,或者内存缓冲区。 - **`keychain-forensic`** —— 基于 `keychain-core` 的 `kc4n6` 分析器:对每个恢复的项进行分类,并标记出高价值的 `Safe Storage` 密钥。 ## 信任但要验证 - **Tier-2 级别已通过 Apple 自家工具的验证。** 测试夹具(fixture)是由 `/usr/bin/security`(Apple 的 Keychain Services CLI)生成的,并且在其机密被 `security find-generic-password` 确认后,*才*交由此 crate 处理该 文件。恢复出完全相同的机密证明了此 crate 与 Apple 的结果一致,而 不仅仅是自洽。详见 [`docs/validation.md`](docs/validation.md)。 - **通过 lint 保证无 panic。** `#![forbid(unsafe_code)]`,`clippy::unwrap_used` 和 `expect_used` 在生产环境中被禁止使用;每一个整数字段的读取都经过经过模糊测试的 `safe-read` crate,每一个长度/偏移量在使用前都进行了边界检查。 - **经过模糊测试。** 在容器导航和加密边界上的 `cargo-fuzz` 目标断言了在任意字节输入下的永不 panic 不变量。 格式参考:社区工具 `chainbreaker`(n0fate)以及 Apple 的开源项目 `securityd` / `libsecurity_cdsa_*`。 [隐私政策](https://securityronin.github.io/keychain-forensic/privacy/) · [服务条款](https://securityronin.github.io/keychain-forensic/terms/) · © 2026 Security Ronin Ltd
标签:Keychain, Rust, 加密算法, 可视化界面, 域渗透, 密码解密, 电子数据取证, 网络流量审计, 通知系统