ReagentX/crabapple
GitHub: ReagentX/crabapple
crabapple 是一个 Rust 库,用于读取、解密和提取由 Finder、iTunes 或 Apple Devices 创建的加密 iOS 备份数据。
Stars: 69 | Forks: 1
# crabapple
`crabapple` 是一个 Rust 库,用于读取、检查和提取由 Finder、Apple Devices 或 iTunes 创建的加密 iOS 备份数据。
受 [`imessage-exporter`](https://github.com/ReagentX/imessage-exporter) 启发,`crabapple` 为任何需要访问 iOS 备份数据的项目提供了灵活的基础。
## 功能
- 加载并解析备份的 `Manifest.plist` 以获取元数据、设备信息和加密参数
- 使用 `PBKDF2`(先 `HMAC-SHA256` 后 `HMAC-SHA1`)派生加密密钥,并通过 AES Key Wrap (`RFC 3394`) 解包保护类密钥
- 解密并查询 `AES-256` 加密的 `Manifest.db`,通过 `rusqlite` 暴露备份文件元数据
- 按保护类检索单个文件并解密(基于单个文件的带有 `PKCS7` 填充的 `AES-CBC`)
- 跨平台支持 macOS、Windows 和 Linux
## 安装
该库可在 [crates.io](https://crates.io/crates/crabapple) 上获取。
## 文档
文档可在 [docs.rs](https://docs.rs/crabapple) 上查看。
## 快速开始
```
use std::{io::copy, fs::File};
use crabapple::{Backup, Authentication};
fn main() -> Result<(), Box> {
// Initialize a backup session for a device UDID with a password
let udid_folder = "/Users/you/Library/Application Support/MobileSync/Backup/DEVICE_UDID";
let auth = Authentication::Password("your_password".into());
let backup = Backup::open(udid_folder, &auth)?;
// List all files in the backup
let entries = backup.entries()?;
for entry in &entries {
println!("{} - {}/{}", entry.file_id, entry.domain, entry.relative_path);
}
// Decrypt and read a file entry as a stream
if let Some(entry) = entries.first() {
let mut stream = backup.decrypt_entry_stream(&entry)?;
// Write the stream to a file
let mut file = File::create("decrypted.txt")?;
copy(&mut stream, &mut file)?;
}
// Alternatively, decrypt and read a file entry into memory
if let Some(entry) = entries.get(2) {
let data = backup.decrypt_entry(&entry)?;
println!("Decrypted {} ({} bytes)", entry.relative_path, data.len());
}
// Get the derived key for use elsewhere:
let derived_key = backup.decryption_key_hex();
Ok(())
}
```
### 使用预派生密钥
预派生密钥可以绕过耗时的密钥派生过程:
```
use crabapple::{Backup, Authentication};
fn main() -> Result<(), Box> {
let udid_folder = "/path/to/backup";
let hex_key = "abcdef0123456789...";
let auth = Authentication::DerivedKey(hex_key.to_string());
let backup = Backup::open(udid_folder, &auth)?;
// ... proceed as normal
Ok(())
}
```
### 获取基本设备信息
您无需打开完整的备份数据库即可检索设备元数据(例如设备名称、iOS 版本和 UDID):
```
use std::path::Path;
use crabapple::backup::device::get_device_basic_info;
fn main() -> Result<(), Box> {
let udid_folder = Path::new("/Users/you/Library/Application Support/MobileSync/Backup/DEVICE_UDID");
let info = get_device_basic_info(udid_folder)?;
println!("Device: {} (iOS {})", info.device_name, info.product_version);
println!("UDID: {}", info.unique_device_id);
Ok(())
}
```
此信息也存在于已解密的 `Backup` 实例中:
```
use crabapple::{Backup, Authentication};
fn main() -> Result<(), Box> {
let udid_folder = "/path/to/backup";
let hex_key = "abcdef0123456789...";
let auth = Authentication::DerivedKey(hex_key.to_string());
let backup = Backup::open(udid_folder, &auth)?;
println!("Device: {} (iOS {})",
backup.lockdown().device_name,
backup.lockdown().product_version
);
println!("UDID: {}", backup.udid()?);
Ok(())
}
```
### 错误处理
`crabapple` 使用自定义的 `BackupError` 枚举进行错误报告。您可以针对特定情况进行匹配:
```
use crabapple::{Backup, Authentication};
use crabapple::error::BackupError;
match Backup::open("/bad/path", &Authentication::Password("pass".into())) {
Ok(b) => println!("Loaded backup successfully"),
Err(BackupError::ManifestPlistNotFound(path)) => eprintln!("Missing Manifest.plist: {}", path),
Err(err) => eprintln!("Error initializing backup: {}", err),
}
```
## 目标版本
该库针对 iOS 当前最新的公开发布版本。它应适用于 iOS 10.2 或更高版本的备份,但可能并非所有功能都可用。
## Crabapple 树

标签:iOS备份, Rust库, SQLite, 可视化界面, 密码学解密, 数据提取, 数据解析, 通知系统