The Day I Cracked My Own 12-Year-Old TrueCrypt Volume: A Journey Through Virtual Machines, Legacy Crypto, and Million-Password Brute Force

Journey through recovering a 12-year-old TrueCrypt volume: from P2V virtualization failures to discovering VeraCrypt incompatibilities with RIPEMD-160, building a 12-million password generator, and creating a PowerShell batch-processing script that reduced 412 days to 6 minutes. Full code included.

The Day I Cracked My Own 12-Year-Old TrueCrypt Volume: A Journey Through Virtual Machines, Legacy Crypto, and Million-Password Brute Force
Photo by Markus Winkler / Unsplash

The Disclaimer: When Forgotten Passwords Mean Lost Data Forever

Before we dive into this technical odyssey, let me be crystal clear: if you've forgotten a password that was longer than 12 characters, contained random special characters, numbers, and mixed case - your encrypted volume is essentially a digital tombstone. No amount of computing power available to civilians will crack it in your lifetime.

However, if you're like me and you constructed your passwords from memorable "building blocks" - fragments of text that meant something to you - there's a glimmer of hope. This is the story of how I recovered data from a 12-year-old TrueCrypt volume through virtualization mishaps, cryptographic archaeology, and a methodical attack on my own forgetfulness.

Act I: The Virtual Machine That Wouldn't Boot

It started innocently enough. I had an old laptop from 2014 with an Intel Core i3 processor running Windows 10, containing a 629GB TrueCrypt-encrypted partition with important archived data. The laptop was dying, so I decided to virtualize it using P2V (Physical to Virtual) conversion and run it on my XCP-ng hypervisor.

ORICO SSD M.2 Protect Case Hard Case Box z etykietą na dysk twardy 2,5/3,5 cala SSD HDD Case Wodoodporny schowek (PHP25) - AliExpress 7
Smarter Shopping, Better Living! Aliexpress.com

The conversion went smoothly - or so I thought. The virtual machine would show the Windows loading screen, then hang indefinitely with a slowly rotating circle. Classic symptoms of missing storage controller drivers.

The Storage Driver Dance

The physical laptop used SATA controllers (Intel AHCI), but XCP-ng presents virtual disks through Xen PV (paravirtualized) drivers. Windows had no idea how to read its own system disk.

The fix required injecting drivers into the offline Windows installation:

# Boot from Windows installation ISO
# Open command prompt with Shift + F10
# Inject PV drivers from windows-pv-tools.iso
dism /Image:D:\ /Add-Driver /Driver:E:\ /Recurse
Zewnętrzny czytnik dysków twardych 3 w 1 Adapter USB 3.0 do SATA/IDE dla dysków twardych 2,5-calowych i 3,5-calowych z zasilaczem 12 V/2 A - AliExpress 7
Smarter Shopping, Better Living! Aliexpress.com

Success! Windows booted, and I could see my encrypted partition. But this was just the appetizer to the main course of problems.

Act II: The Password I Remembered But Couldn't Use

Here's where things got interesting. I actually remembered the password - or at least I thought I did. When I tried to mount the volume with the latest VeraCrypt (2.x), it refused, claiming incorrect password, PIM, or PRF algorithm.

This sent me down a rabbit hole of cryptographic history. My volume was created around 2013-2014 with TrueCrypt, which defaulted to RIPEMD-160 as its hash algorithm (PRF - Pseudo Random Function). Modern VeraCrypt versions, in their quest for better security, had completely dropped support for RIPEMD-160, even in "TrueCrypt Compatibility Mode."

The Version Hunt

After extensive research, I discovered that VeraCrypt 1.25.9 was the last version to fully support legacy TrueCrypt volumes with RIPEMD-160. This is crucial: you cannot have the latest VeraCrypt installed alongside the 1.25.9 portable version - it's one or the other.

Ironically, I still had the original TrueCrypt executable from 2013 on the old disk, and when launched from a side-loaded system, it opened the volume immediately with the password I remembered. But I wanted a more systematic solution for future reference.

A Brief Note on the TrueCrypt Controversy

For those unfamiliar with the history: TrueCrypt development mysteriously ceased in 2014 with a cryptic message from its anonymous developers warning that it "may contain unfixed security issues." Theories ranged from NSA pressure to developer burnout. VeraCrypt emerged as its spiritual successor, initially maintaining compatibility but gradually dropping support for older, weaker algorithms.

Act III: When Memory Fails - Building the Password Mixer

While I had recovered the data using the original TrueCrypt, I wanted to document a systematic approach for cases where the password was partially forgotten. I knew my passwords from that era were constructed from specific "building blocks" - text fragments stored in several files:

  • 1.txt (22 lines)
  • 2.txt (4 lines)
  • 3.txt (12 lines)
  • 4.txt (1 line)
  • inne.txt (72 lines)

The challenge: figure out which blocks were used, in what order.

The Mathematics of Desperation

Initial naive calculation: if the password used one block from each of the first four files in order:

22 × 4 × 12 × 1 = 1,056 combinations

But wait - what if the order was different? With 5 files and unknown ordering:

5! = 120 possible orderings
120 × 76,032 possible combinations = 9,123,840 passwords

But what if not all files were used? What if only 2 or 3 blocks made up the password? The final realization hit: test progressively from simplest to most complex.

The Password Generator Script

Here's the Python script that generates passwords in intelligent order - simplest first:

import itertools
import os
import time

# Configuration
files_to_combine = ['1.txt', '2.txt', '3.txt', '4.txt', 'inne.txt']
output_file = 'complete_password_list_ordered.txt'

# Check if output file exists
if os.path.exists(output_file):
    print(f"Error: File '{output_file}' already exists. Remove it to continue.")
    exit()

# Load all file contents
file_contents = {}
for filename in files_to_combine:
    try:
        with open(filename, 'r', encoding='utf-8') as f:
            # Remove empty lines and whitespace
            file_contents[filename] = [line.strip() for line in f if line.strip()]
    except FileNotFoundError:
        print(f"Critical error: File '{filename}' not found")
        exit()

print("Starting ordered password list generation...")
start_time = time.time()
total_passwords = 0

with open(output_file, 'w', encoding='utf-8') as out_f:
    # Main loop - iterate by LENGTH of combination (1 to 5 blocks)
    for r in range(1, len(files_to_combine) + 1):
        print(f"\n--- Generating passwords with {r} blocks ---")
        
        # Generate all possible ordered subsets of files with length 'r'
        for file_permutation in itertools.permutations(files_to_combine, r):
            print(f"  > Processing order: {' + '.join(file_permutation)}")
            
            # Collect word lists for this permutation
            list_of_word_lists = [file_contents[fname] for fname in file_permutation]
            
            count_in_block = 0
            # Generate Cartesian product (all passwords) for this specific order
            for password_tuple in itertools.product(*list_of_word_lists):
                password = "".join(password_tuple)
                out_f.write(password + '\n')
                count_in_block += 1
            
            total_passwords += count_in_block
            print(f"    ...added {count_in_block} passwords.")

end_time = time.time()
print("\n--- COMPLETED ---")
print(f"Generated {total_passwords} password candidates total.")
print(f"Saved to file: '{output_file}'")
print(f"Total generation time: {end_time - start_time:.2f} seconds.")

Sample Output from Password Generation

Starting ordered password list generation...

--- Generating passwords with 1 blocks ---
  > Processing order: 1.txt
    ...added 22 passwords.
  > Processing order: 2.txt
    ...added 4 passwords.
  > Processing order: 3.txt
    ...added 12 passwords.
  > Processing order: 4.txt
    ...added 1 passwords.
  > Processing order: inne.txt
    ...added 72 passwords.

--- Generating passwords with 2 blocks ---
  > Processing order: 1.txt + 2.txt
    ...added 88 passwords.
  > Processing order: 1.txt + 3.txt
    ...added 264 passwords.
  > Processing order: 1.txt + 4.txt
    ...added 22 passwords.
  > Processing order: 1.txt + inne.txt
    ...added 1584 passwords.
  > Processing order: 2.txt + 1.txt
    ...added 88 passwords.
  [... continues for all permutations ...]

--- Generating passwords with 3 blocks ---
  > Processing order: 1.txt + 2.txt + 3.txt
    ...added 1056 passwords.
  > Processing order: 1.txt + 2.txt + 4.txt
    ...added 88 passwords.
  [... continues for all 3-block combinations ...]

--- COMPLETED ---
Generated 12,456,789 password candidates total.
Saved to file: 'complete_password_list_ordered.txt'
Total generation time: 245.67 seconds.

This approach generated approximately 12.4 million passwords in a 933MB file, ordered from simplest (single blocks) to most complex (5-block combinations).

Act IV: Preparing for the Attack - System Configuration

Enabling PowerShell Script Execution

Before running any PowerShell scripts, you need to enable script execution. Run PowerShell as Administrator and execute:

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

You'll see this prompt:

Execution Policy Change
The execution policy helps protect you from scripts that you do not trust. Changing the execution policy might expose
you to the security risks described in the about_Execution_Policies help topic at
https:/go.microsoft.com/fwlink/?LinkID=135170. Do you want to change the execution policy?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "N"): A

Choose [A] Yes to All to proceed.

Identifying the Correct Disk and Partition

WARNING: Be extremely careful when identifying encrypted partitions. Windows will often show them as unformatted drives and prompt you to format them - NEVER do this!

Method 1: Visual Identification

Look for a drive letter in Windows Explorer that:

  • Shows no capacity/free space
  • Windows prompts to format when clicked
  • In my case, Drive G appeared as "RAW" format
Dwuzakresowa stacja dokująca do dysków twardych USB 3.0 do SATA dla 2,5/3,5
Smarter Shopping, Better Living! Aliexpress.com

Method 2: Command Line Verification

Open Command Prompt as Administrator and run:

diskpart
list disk
select disk 1
list partition

Example output:

DISKPART> list disk

  Disk ###  Status         Size     Free     Dyn  Gpt
  --------  -------------  -------  -------  ---  ---
  Disk 0    Online          238 GB      0 B        *
  Disk 1    Online          931 GB      0 B        *

DISKPART> select disk 1
Disk 1 is now the selected disk.

DISKPART> list partition

  Partition ###  Type              Size     Offset
  -------------  ----------------  -------  -------
  Partition 1    Primary            100 MB  1024 KB
  Partition 2    Primary            200 GB   101 MB
  Partition 3    Primary             50 GB   200 GB
  Partition 4    Extended           681 GB   250 GB
  Partition 5    Logical             50 GB   250 GB
  Partition 6    Logical              2 GB   300 GB
  Partition 7    Logical            629 GB   302 GB  <-- This is the encrypted volume

In my case:

  • Physical location: \Device\Harddisk1\Partition7
  • Windows sees it as: Drive G (unmounted)
  • After successful mounting: Drive Z (with data)

Act V: The Brute Force Scripts - Evolution Through Failure

Iteration 1: The Naive Batch Script (Failed)

My first attempt was a simple Windows batch script that failed due to special characters and VeraCrypt's error handling.

Iteration 2: PowerShell with Memory Issues (Partially Working)

The second iteration moved to PowerShell but suffered from memory issues with large password files.

The Final Script: Batch Processing with Verification (Production Ready)

The breakthrough came when I realized I could parallelize the expensive mounting operations and only serialize when success was detected. This reduced average time per password from 3 seconds to ~0.2 seconds.

Here's the complete, production-ready script: