{"id":51595166,"url":"https://github.com/securityronin/veracrypt-forensic","last_synced_at":"2026-07-16T23:01:05.731Z","repository":{"id":370756160,"uuid":"1296675926","full_name":"SecurityRonin/veracrypt-forensic","owner":"SecurityRonin","description":"VeraCrypt/TrueCrypt forensic library — brute the header PRF+cipher from a password, recover the master key, and decrypt the volume (AES/Serpent/Twofish, 5 PRFs, hidden volumes). Panic-free, no unsafe.","archived":false,"fork":false,"pushed_at":"2026-07-10T19:07:56.000Z","size":72,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-11T18:16:29.315Z","etag":null,"topics":["cryptography","dfir","digital-forensics","encryption","forensics","incident-response","rust","truecrypt","veracrypt","xts"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SecurityRonin.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-07-10T16:04:16.000Z","updated_at":"2026-07-11T12:26:03.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/SecurityRonin/veracrypt-forensic","commit_stats":null,"previous_names":["securityronin/veracrypt-forensic"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/SecurityRonin/veracrypt-forensic","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SecurityRonin%2Fveracrypt-forensic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SecurityRonin%2Fveracrypt-forensic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SecurityRonin%2Fveracrypt-forensic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SecurityRonin%2Fveracrypt-forensic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SecurityRonin","download_url":"https://codeload.github.com/SecurityRonin/veracrypt-forensic/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SecurityRonin%2Fveracrypt-forensic/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35400291,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-12T02:00:06.386Z","response_time":87,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cryptography","dfir","digital-forensics","encryption","forensics","incident-response","rust","truecrypt","veracrypt","xts"],"created_at":"2026-07-11T18:01:35.973Z","updated_at":"2026-07-12T19:00:52.591Z","avatar_url":"https://github.com/SecurityRonin.png","language":"Rust","funding_links":["https://github.com/sponsors/h4x0r"],"categories":[],"sub_categories":[],"readme":"# veracrypt-forensic\n\n[![Crates.io: veracrypt-core](https://img.shields.io/crates/v/veracrypt-core.svg?label=veracrypt-core)](https://crates.io/crates/veracrypt-core)\n[![Crates.io: veracrypt-forensic](https://img.shields.io/crates/v/veracrypt-forensic.svg?label=veracrypt-forensic)](https://crates.io/crates/veracrypt-forensic)\n[![Docs.rs](https://img.shields.io/docsrs/veracrypt-core?label=docs.rs)](https://docs.rs/veracrypt-core)\n[![Rust 1.81+](https://img.shields.io/badge/rust-1.81%2B-blue.svg)](https://www.rust-lang.org)\n[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)\n[![Sponsor](https://img.shields.io/badge/sponsor-h4x0r-ea4aaa?logo=githubsponsors)](https://github.com/sponsors/h4x0r)\n\n[![CI](https://github.com/SecurityRonin/veracrypt-forensic/actions/workflows/ci.yml/badge.svg)](https://github.com/SecurityRonin/veracrypt-forensic/actions/workflows/ci.yml)\n[![Coverage](https://img.shields.io/badge/coverage-100%25%20lines-brightgreen.svg)](docs/validation.md)\n[![unsafe forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance)\n[![Security advisories](https://img.shields.io/badge/advisories-clean-success.svg)](https://rustsec.org)\n\n**Unlock a VeraCrypt (or legacy TrueCrypt) volume from its password and read the\nplaintext — a from-scratch, pure-Rust decryptor validated byte-for-byte against\nboth the real VeraCrypt binary and `cryptsetup` on a real volume.**\n\nNo `veracrypt` binary, no `cryptsetup`, no FUSE, no mounting: one library that\nbrutes the header PRF and cipher from a password, recovers the master key, and\ndecrypts the data area as AES-256 or Twofish-256 XTS.\n\n```rust,ignore\nuse std::fs::File;\nuse veracrypt::VeraVolume;\n\n// Unlock a VeraCrypt volume with its password (no PIM).\nlet mut vol = VeraVolume::unlock_with_password(File::open(\"container.vc\")?, b\"passphrase\")?;\n\nlet mut first = [0u8; 512];\nvol.read_at(0, \u0026mut first)?;     // first decrypted sector of the data area\nprintln!(\"{:?} / {}\", vol.info().flavor, vol.info().cipher.name());\n# Ok::\u003c(), Box\u003cdyn std::error::Error\u003e\u003e(())\n```\n\n## Scope\n\nThis build brutes the header across **all five VeraCrypt PRFs** and decrypts\n**both single ciphers**, with support for a PIM and for normal *and* hidden\nvolumes:\n\n| Axis | Supported |\n|---|---|\n| PRF (header key derivation) | SHA-512 · SHA-256 · Whirlpool · Streebog-512 · RIPEMD-160 |\n| Cipher (data area) | AES-256-XTS · Serpent-256-XTS · Twofish-256-XTS · all VeraCrypt cascades |\n| PIM | yes — `unlock_with_pim` / `unlock_hidden_with_pim` |\n| Volume layout | normal (header @ 0) · hidden (header @ 64 KiB) |\n| Flavor | VeraCrypt (`VERA`) · legacy TrueCrypt (`TRUE`) |\n\n`VeraVolume::unlock_with_password(reader, password)` tries every PRF × cipher\nuntil one decrypts the header to a valid `VERA`/`TRUE` signature with both CRC-32s\nmatching, then exposes a plaintext `Read + Seek` view (`read_at`).\n`unlock_hidden_with_password` reads the hidden header at 64 KiB — used to access,\nor to prove the presence of, a deniable hidden volume.\n\nAll three single ciphers — **AES-256**, **Serpent-256**, **Twofish-256** — are\nsupported, each via an audited RustCrypto crate (Serpent through\n`serpent::Serpent::new_from_slice`, which takes the full 256-bit key), and so are\n**all VeraCrypt cipher cascades** (AES-Twofish, AES-Twofish-Serpent, Serpent-AES,\nSerpent-Twofish-AES, Twofish-Serpent) — stacked XTS layers keyed exactly as\ncryptsetup's `TCRYPT_decrypt_hdr`. `VolumeInfo::cipher_display()` names the chain\n(e.g. `aes-twofish-serpent`). See [`docs/RESEARCH.md`](docs/RESEARCH.md).\n\n## The two-crate split\n\nFollowing the fleet reader/analyzer standard:\n\n| Crate | Role | Emits |\n|---|---|---|\n| **`veracrypt-core`** | reader / decryptor (`aes` · `twofish` · `xts-mode` · `pbkdf2` · `sha2` · `whirlpool` · `streebog` · `ripemd`) | plaintext `Read + Seek` view + typed `VolumeInfo` |\n| **`veracrypt-forensic`** | anomaly analyzer over the recovered facts | graded observations |\n\n### Analyzer findings\n\n| Code | Severity | Meaning |\n|---|---|---|\n| `VC-LEGACY-TRUECRYPT` | Low | the volume is a legacy TrueCrypt (not VeraCrypt) container |\n| `VC-HIDDEN-VOLUME-DECLARED` | Medium | the outer header declares a hidden volume (deniable-encryption indicator) |\n| `VC-CIPHER-INVENTORY` | Info | the recovered PRF, cipher, and data-area offset |\n\nFindings are **observations, never verdicts** — the examiner draws conclusions.\n\n## Trust but verify\n\n- **Every primitive is an audited RustCrypto crate** — `aes`, `twofish`,\n  `xts-mode`, `pbkdf2`, `hmac`, `sha2`, `whirlpool`, `streebog`, `ripemd`,\n  `crc32fast`. No cryptography is hand-rolled.\n- **Unimpeachable Tier-1**: on a real VeraCrypt volume with a published password,\n  the decrypted sectors of **three independent implementations agree\n  byte-for-byte** — VeraCrypt 1.26.20 (Idrix, the format's own reference),\n  `cryptsetup` 2.7.0 (an independent reimplementation), and this crate. See\n  [`docs/validation.md`](docs/validation.md).\n- **Panic-free, bounds-checked** parsing of untrusted volumes;\n  `unwrap`/`expect` denied in production code (`#![forbid(unsafe_code)]`); the\n  header parser is fuzzed.\n\n[Privacy Policy](https://securityronin.github.io/veracrypt-forensic/privacy/) · [Terms of Service](https://securityronin.github.io/veracrypt-forensic/terms/) · © 2026 Security Ronin Ltd\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsecurityronin%2Fveracrypt-forensic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsecurityronin%2Fveracrypt-forensic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsecurityronin%2Fveracrypt-forensic/lists"}