Open Source · MIT License

Encrypted Vault

A secure, user-friendly file encryption tool with both command-line and graphical interfaces. Protect your sensitive files with military-grade encryption using AES-256-GCM and Argon2id key derivation.

✓ AES-256-GCM ✓ Argon2id KDF Python 3.8+ PyQt6 GUI MIT License

Overview

Encrypted Vault is a portable, GitHub-friendly encrypted file storage solution. Every file you add is individually encrypted with a unique random 256-bit key. All metadata is stored in an opaque binary format — no readable JSON or plain-text headers that could expose sensitive information.

The application supports a full-featured graphical interface built with PyQt6 and a powerful CLI for scripting and automation. Built-in viewers let you preview images, PDFs, videos, audio, and text files directly from within the vault without writing anything to disk.

Features

🔒

Strong Encryption

AES-256-GCM authenticated encryption with unique per-file random 256-bit keys. Prevents both eavesdropping and data tampering.

🔑

Secure Key Derivation

Argon2id algorithm with SHA3-512 pre-hashing. Memory-hard and side-channel resistant. Configurable time/memory/parallelism parameters.

🖥️

Dual Interface

Full-featured PyQt6 GUI with tree view, search, and drag-and-drop, plus a powerful CLI for scripting and automation pipelines.

📦

GitHub-Friendly

All-binary vault format with opaque metadata. No readable headers that could leak filenames, sizes, or other sensitive information.

📁

Folder Support

Add entire folder hierarchies and preserve directory structure using --relpath. Extract individual files or bulk-export everything.

👁️

Built-in Viewers

Preview images, PDFs, videos, audio, and text files directly from the vault — no temporary unencrypted files written to disk.

🔄

Master Key Rotation

Change your passphrase and Argon2 parameters at any time without re-encrypting individual files. Only the master key wrapper is updated.

📤

Portable Executable

Package as a standalone .exe using PyInstaller. Distribute to users who don't have Python installed.

Prerequisites

  • Python 3.8 or higherDownload Python
  • pip — Python package manager (bundled with Python 3.4+)
  • virtualenv (recommended) — for isolated environments

Dependencies

PackageVersionPurpose
cryptography≥ 41.0.0AES-256-GCM encryption primitives
PyQt6≥ 6.5.0Desktop GUI framework
PyQt6-WebEngine≥ 6.5.0PDF viewing support in GUI
pycryptodome≥ 3.18.0Additional cryptographic utilities
argon2-cffi≥ 25.1.0Argon2id key derivation
Pillow≥ 12.1.0Image processing & preview
pyinstallerlatestPackaging standalone executables

Installation

  1. Clone the repository
    git clone https://github.com/AadithyanRaju/Encrypted-Vault.git
    cd Encrypted-Vault
  2. Create a virtual environment (recommended)
    python3 -m venv .venv
    source .venv/bin/activate
    python -m venv .venv
    .venv\Scripts\Activate.ps1
    python -m venv .venv
    .venv\Scripts\activate.bat
  3. Install dependencies
    pip install -r requirements.txt

GUI Mode

The graphical interface provides a full file-manager-like experience for your encrypted vault.

Launch the GUI

# Open the GUI without specifying a vault
python src/efs.py gui

# Open the GUI with a vault pre-loaded
python src/efs.py gui /path/to/vault

GUI Capabilities

  • 🔓 Unlock / lock vault — enter your master passphrase to decrypt the metadata index
  • Add files & folders — drag-and-drop or use the file browser, with optional relative path
  • 📂 Tree view with search — browse your encrypted files hierarchically and filter by name
  • 👁️ In-vault preview — images, PDFs, videos, audio, and text without extracting to disk
  • 💾 Extract files — save individual files or bulk-export the entire vault
  • ✏️ Rename & delete — manage files without decrypting them
  • 🔑 Change master password — rotate your passphrase and optionally adjust Argon2 parameters

CLI Mode

The command-line interface is designed for scripting, automation, and headless environments.

Initialize a New Vault

# Default Argon2 parameters
python src/efs.py init /path/to/vault --passphrase "your-secure-passphrase"

# Custom Argon2 parameters for higher security
python src/efs.py init /path/to/vault --passphrase "your-passphrase" -t 8 -m 524288 -p 4
FlagDefaultDescription
-t4Argon2 time cost (iterations)
-m262144 (256 MiB)Argon2 memory cost in KiB
-p2Argon2 parallelism factor

Add Files

# Add a single file
python src/efs.py add /path/to/vault /path/to/file.txt --passphrase "your-passphrase"

# Preserve the original folder path inside the vault
python src/efs.py add /path/to/vault /path/to/file.txt \
  --relpath "documents/file.txt" --passphrase "your-passphrase"

List Encrypted Files

python src/efs.py ls /path/to/vault --passphrase "your-passphrase"

Extract Files

python src/efs.py extract /path/to/vault <file-id> /output/path.txt \
  --passphrase "your-passphrase"

Remove a File

python src/efs.py rm /path/to/vault <file-id> --passphrase "your-passphrase"

Rename a File

python src/efs.py rename /path/to/vault <file-id> "new-name.txt" \
  --passphrase "your-passphrase"

Rotate Master Key

# Change passphrase only
python src/efs.py rotate-master /path/to/vault \
  --passphrase "old-passphrase" --new-passphrase "new-passphrase"

# Change passphrase and update Argon2 parameters
python src/efs.py rotate-master /path/to/vault \
  --passphrase "old-passphrase" --new-passphrase "new-passphrase" \
  -t 8 -m 524288 -p 4
💡 Tip

Master key rotation only rewrites the vault header — individual file blobs are not re-encrypted, so it is fast even for large vaults.

CLI Reference

CommandDescription
init <vault>Create and initialize a new encrypted vault
add <vault> <file>Add a file to the vault
ls <vault>List all files stored in the vault
extract <vault> <id> <out>Extract a file from the vault to the given output path
rm <vault> <id>Remove a file from the vault
rename <vault> <id> <name>Rename a file without decrypting it
rotate-master <vault>Change the master passphrase (and optionally Argon2 parameters)
gui [vault]Launch the graphical interface, optionally pre-loading a vault

Global Options

OptionDescription
--passphrase <str>Current master passphrase (required for all vault operations)
--new-passphrase <str>New master passphrase for rotate-master
--relpath <path>Virtual path inside the vault when adding files (preserves folder structure)
-t <int>Argon2 time cost — default 4
-m <int>Argon2 memory cost in KiB — default 262144
-p <int>Argon2 parallelism — default 2

Vault Structure

When you initialize a vault at /path/to/vault, the following directory structure is created on disk:

vault/
├── vault.enc # Binary encrypted metadata index
└── blobs/
    ├── <uuid-1>.bin # Encrypted file blob (nonce + ciphertext)
    ├── <uuid-2>.bin
    └── ...
  • vault.enc — holds the encrypted metadata index (filenames, UUIDs, per-file keys). Nothing is readable without the correct passphrase.
  • blobs/<uuid>.bin — each blob is the raw nonce followed by the AES-256-GCM ciphertext of a single file. The UUID is meaningless without the metadata.

Binary Format

The vault.enc header is a fixed-size 45-byte binary structure followed by the encrypted metadata ciphertext.

FieldSizeDescription
Magic4 bytesASCII "EFS1" — identifies the file format
Version1 byte0x01 — format version
T-Cost4 bytesArgon2 time cost (big-endian uint32)
M-Cost4 bytesArgon2 memory cost in KiB (big-endian uint32)
Parallelism4 bytesArgon2 parallelism factor (big-endian uint32)
Salt16 bytesCryptographically random KDF salt
Nonce12 bytes96-bit random AEAD nonce
CiphertextvariableAES-256-GCM encrypted JSON metadata

File Blob Format

Each blobs/<uuid>.bin file has a minimal format:

FieldSizeDescription
Nonce12 bytes96-bit random nonce for this blob
CiphertextvariableAES-256-GCM ciphertext of the original file

Project Structure

Encrypted-Vault/
├── src/
│   ├── efs.py # Main entry point
│   ├── crypto/
│   │   ├── aead.py # AES-256-GCM encrypt / decrypt
│   │   └── hash.py # SHA3-512 + Argon2id KDF
│   ├── storage/
│   │   └── vault.py # Binary vault read / write
│   ├── utils/
│   │   ├── core.py # init, add, ls, extract commands
│   │   ├── maintain.py # rename, rm, rotate-master commands
│   │   ├── dataModels.py # Data structures & constants
│   │   └── helper.py # Shared utility functions
│   └── ui/
│       ├── cli.py # CLI argument parser
│       ├── gui.py # Main PyQt6 GUI application
│       ├── gui_components/
│       │   ├── dialogs.py # Dialog windows
│       │   ├── file_operations.py # Add / extract / remove
│       │   ├── tree_operations.py # Tree view management
│       │   └── vault_operations.py # Unlock / lock / rotate
│       ├── ImageViewer.py # In-vault image preview
│       ├── PDFViewer.py # In-vault PDF preview
│       ├── VideoPlayer.py # In-vault video playback
│       ├── AudioPlayer.py # In-vault audio playback
│       └── TextEditor.py # In-vault text viewer / editor
├── requirements.txt # Python dependencies
├── vault.exe.spec # PyInstaller specification
├── icon.ico # Application icon
└── LICENSE # MIT License

Security Details

Encryption

  • Algorithm: AES-256-GCM — authenticated encryption; ciphertext integrity is cryptographically verified on every read.
  • Key size: 256-bit (32 bytes) per-file random key, independently generated for every file.
  • Nonce: 96-bit random nonce per encryption operation — never reused.
  • Key wrapping: Per-file keys are encrypted with the master key before being stored in vault.enc.

Key Derivation

  • Algorithm: Argon2id — memory-hard, resists GPU/ASIC brute-force and side-channel attacks.
  • Pre-hashing: The passphrase is pre-hashed with SHA3-512 before being passed to Argon2id for additional length-normalisation.
  • Salt: 128-bit random salt stored in vault.enc — unique per vault, regenerated on master key rotation.
  • Configurable parameters: Time cost, memory cost, and parallelism are tunable to match your hardware.
⚠️ Critical Warnings

Passphrase loss = permanent data loss. There is no backdoor or recovery mechanism.
Always store your passphrase securely (e.g., a password manager or encrypted offline backup).

Threat Model

Encrypted Vault protects files at rest. It does not protect:

  • Files while they are unlocked in memory
  • Against malware or keyloggers running on your system
  • Against an adversary with physical access to an unlocked vault
  • Network transmission (use HTTPS/SSH for transfers)
⚠️ Not a Replacement For

Full-disk encryption (BitLocker, FileVault, LUKS), operating system security, enterprise key management systems, or network-level security measures.

Secure Storage Recommendations

  • Never commit passphrases or unencrypted secrets to version control.
  • Set restrictive filesystem permissions on your vault directory (chmod 700 on Linux/macOS).
  • Store vault.enc and blobs/ in a location with appropriate access controls.
  • Keep all dependencies up to date to patch security vulnerabilities.

Best Practices

  • Use a strong, unique passphrase — 20+ characters, mixed case, numbers, and symbols.
  • Enable full-disk encryption on your system (BitLocker / FileVault / LUKS) as a complementary layer.
  • Keep your operating system and dependencies updated to patch security vulnerabilities.
  • Use higher Argon2 parameters (-t, -m) on powerful machines for better brute-force resistance.
  • Back up your encrypted vault to multiple locations (local + cloud) to protect against hardware failure.
  • Rotate your master key periodically or immediately after any suspected passphrase exposure.
💡 Tip

Because the vault format is GitHub-friendly, you can push your encrypted vault to a private GitHub repository as an off-site backup — the blobs are opaque binary files that Git handles efficiently.

Building a Standalone Executable

You can bundle Encrypted Vault into a self-contained .exe (or binary on Linux/macOS) that doesn't require Python to be installed on the target machine.

pyinstaller vault.exe.spec

The packaged application will be created in the dist/ directory as vault.exe. You can distribute this file as a standalone application.

ℹ️ Note

PyInstaller must be installed (pip install pyinstaller) and the vault.exe.spec configuration file must be present in the repository root.

Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository

    Click Fork on GitHub to create your own copy.

  2. Create a feature branch
    git checkout -b feature/your-amazing-feature
  3. Make your changes

    Keep changes focused, minimal, and well-tested.

  4. Commit with a descriptive message
    git commit -m "feat: add support for XYZ"
  5. Open a Pull Request

    Push your branch and open a PR against the main branch describing your changes.

License

This project is licensed under the MIT License. See the LICENSE file for details.

Copyright © 2025 Aadithyan Raju

Built with cryptography, PyQt6, and argon2-cffi.

⚠️ Disclaimer

This software is provided "as is" without warranty of any kind. Use at your own risk. The authors are not responsible for data loss, security breaches, or any other damages resulting from the use of this software. Always maintain backups of important data.