Decrypt and unpack Seedvault backups (GrapheneOS/Seedvault format) into extracted files and APK splits.
- File backups (v0) — repos ending in
.svwith*.SeedSnapsnapshots - App backups (v2) — repos with
*.snapshotfiles; extracts APK splits only - Crypto — mnemonic (BIP39) → PBKDF2-SHA512 → HKDF stream keys, then Tink AES-GCM-HKDF streaming decryption
Requires Go 1.22+.
go test ./...
go build -o seedvault-decrypt.exe ./cmd/seedvault-unpackOn Windows, the built binary will be seedvault-decrypt.exe.
seedvault-decrypt.exe \
--input /path/to/.SeedVaultAndroidBackup \
--mnemonic "word1 word2 ... word12" \
--out ./extracted--input: Storage root or a single repo directory--mnemonic: 12-word BIP39 recovery phrase (case-sensitive)--out: Output directory--only-file: Extract file backups only--only-app: Extract app backups only--snapshots: Comma-separated filter: millisecond timestamps (file) or SHA-256 hashes (app)
- File backups:
<out>/file-backups/<timestamp>/<path>/<name> - App APK splits:
<out>/app-backups/<snapshot-hash>/<package>/<split>.apk
If the mnemonic is incorrect, decryption fails with cipher: message authentication failed.
This tool’s cryptographic details (AAD/stream key derivation, padding, and backup format handling) were derived by reviewing upstream source code:
- GrapheneOS Seedvault (format/crypto reference)
- seedvault-extractor (legacy extractor logic used for BIP39 wordlist + earlier implementation patterns)
- BIP39 English word list: bitcoin/bips
Third-party libraries used (see their upstream licenses):
- Google Tink
- klauspost/compress (
zstd) golang.org/x/crypto(PBKDF2)github.com/golang/protobuf(protobuf unmarshalling for the adapted message models)