A command-line tool for encrypting and decrypting a file or a directory using modern encryption algorithms and password-based key derivation. Additionally, it can use a USB security key, a key file, bzip2 compression and an output file split. The contents of a directory are concatenated into an archive.
Security Notes: This software is experimental. There wasn't any security audit. Do not use in production. USE AT YOUR OWN RISK!
- Dual encryption with ciphers AES-GCM-SIV and XChaCha20Poly1305
- Password-based key derivation (Argon2id)
- Optional USB security key / FIDO authenticator to supplement the password
- Optional key file (its first 64 MB) can be used additionally to the password
- Optional bzip2 compression before encryption
- Optional split of output into files of user-defined number and size
- Prints SHA256 checksum for each file at end of encryption (if checksum is verified by user before decryption, e.g. rollback to older backup versions by an adversary could be detected)
- Progress indicator
- Handles large files efficiently by parallel processing them in chunks
- CLI interface
- Rust toolchain
- Supports MacOS, Linux, Windows
- Cross-platform: e.g. an archive created on Linux can be extracted on Windows and vice versa
- Symbolic links
- Hard links
- Sparse files: the size of sparse holes might change on cross-platform extraction
- Modification and access time stamps
- File permissions: only on Unix-like systems (MacOS, Linux)
- Stores relative paths
- Building an archive (i.e. reading files) is done in parallel for improved performance
- FIDO2 authenticator
- PIN must be set on device and need to be entered by user
- Non-discoverable (non-resident) credentials
- Hmac-secret
- Tested with Token2 PIN+ Release3.3
An encrypted file can be bound to only one USB security key. If you want to protect data against hardware failure of USB security key, you should encrypt the data again with another USB security key.
Application for encryption and decryption of file or directory.
If no option is given, input is encrypted. Providing a directory creates an encrypted archive.
With option -s the encrypted output is split into files with extensions .c00, .c01, .c02, ...
If a file ending in .c00 is decrypted, the whole split series will be read.
Usage: cryptcrypt [OPTIONS] <FILE_OR_DIRECTORY>
Arguments:
<FILE_OR_DIRECTORY> File that should be encrypted or decrypted. If a directory is given, its contents is archived and encrypted
Options:
-d, --decrypt Decrypt file (with extension '.cce' or for split series '.c00')
-k, --keyfile <KEYFILE> Additional key file to supplement the password
-l, --list-archive List elements of an archive file, do not create its elements
-o, --out-dir <OUT_DIR> Output directory, it is created if it does not exist
-s, --split <SPLIT> Split encrypted data into pieces of binary byte sizes (e.g. 2g,3g,1g) [G|g|M|m|K|k]
-u, --usb-key Additional USB security key/FIDO authenticator to supplement the password, automatically detected on decryption
-v, --verbose Show details about operations
-z, --compress Compress data before encryption, automatically detected on decryption
-h, --help Print help
-V, --version Print version
git clone https://github.com/JoergDF/cryptcrypt.git
cd cryptcrypt
cargo run --releaseIf you use Visual Studio for Rust, select clang components for installation. And add directory of clang-cl.exe to the environment variable PATH:
For Visual Studio 2026 Community Edition it is (on x86) C:\Program Files\Microsoft Visual Studio\18\Community\VC\Tools\Llvm\x64\bin
or (on Arm64) C:\Program Files\Microsoft Visual Studio\18\Community\VC\Tools\Llvm\ARM64\bin.
-
Encrypt a file:
cryptcrypt file.binPrompts you to enter a password (with confirmation).
Creates output filefile.bin.cce. Overwrites file, if it already exists. -
Archive and encrypt a directory (with all its sub-directories and files):
cryptcrypt directoryCreates output file
directory.cce. Overwrites file, if it already exists. -
Encrypt a file with additional key file, compress and split output files into sizes of 1 KBytes, 2 MBytes and remaining bytes, write output files into folder
output_enc:cryptcrypt -k keyfile.bin -z -s 1k,2m -o output_enc file.bin -
Encrypt a file with a USB security key. Prompts shown:
cryptcrypt -u file.bin Enter password: Repeat password: Enter PIN of USB security key: Registering USB security key... - Touch the sensor on the authenticator Requesting data from USB security key... - Touch the sensor on the authenticator USB security key end -
Decrypt a file:
cryptcrypt -d file.bin.ccePrompts you to enter a password.
Creates output filefile.bin. Overwrites file, if it already exists. -
Decrypt a split series of files with additional key file (compression and USB security key usage are coded in the encrypted file), write output into folder
output_dec:cryptcrypt -k keyfile.bin -o output_dec -d file.bin.c00
Encryption process:
Data structure of encrypted output file:
Description:
The header of an encrypted file consists of an unencrypted part and an encrypted part:
-
Unencrypted header part:
It contains two salts used to encrypt the second part of the header:- A random salt used to create a key from the password with Argon2id.
- A different random salt used to derive two keys from that password-derived key using HKDF-SHA256. These two final keys are used to encrypt the second header part with XChaCha20-Poly1305 and AES-256-GCM-SIV.
-
Encrypted header part:
It contains two new salts used to encrypt the file body and additional metadata:- A random salt where the inputs to Argon2id for generating a primary key are: the password, an optional USB security key's hmac-secret, and an optional key file hash.
- Another random salt used to derive two keys from the primary key using HKDF-SHA256. These two keys are used to encrypt the file's body with XChaCha20-Poly1305 and AES-256-GCM-SIV.
If a key file is used, its first 64 MB is hashed with sha3-512. If a USB security key is used, a credential ID and a random salt are stored and used to retrieve an hmac-secret from the key; otherwise, their space is filled with random data. Additionally, the following data and flags are saved: the file format version, and flags indicating whether compression, an archive, a key file, or a USB security key is used. The overall header length remains constant regardless of which options are selected.
The encryption of the file's body follows this procedure:
- Read a 1 MB chunk from the input file (the last chunk may be smaller). Keep a zero-based sequence number for each chunk and mark the final chunk with a flag.
- If compression is enabled, compress the chunk using bzip2. Its variable-sized output is copied into fixed-size, 1 MB chunks. (The chunk size should not leak information about the cleartext.)
- First-pass encryption: Encrypt the chunk with XChaCha20-Poly1305 using a fresh random base nonce generated per chunk. The implementation derives the actual encryption nonce by XOR'ing the base nonce with the chunk's sequence number and the final-chunk flag. The original base nonce is stored after the ChaCha ciphertext so the per-chunk nonce can be recomputed during decryption. Reordering or truncating the chunk sequence causes a decryption error. Additional associated data (AAD) used for authentication includes: the file format version, the string "Cha", and the file ID.
- Second-pass encryption: Encrypt the output of step 3 with AES-256-GCM-SIV using a fresh random nonce. AAD contains: the file format version, the string "Aes", the file ID, the chunk count, and the final flag. The AES nonce is stored after the AES ciphertext and written to the output file.
- Repeat steps 1 through 4 until all input is processed.
Keys, the password, the PIN, and the hmac-secret value are zeroized when they are no longer needed or when their memory is freed. Since the password may remain in memory for a relatively long time before being used again (especially when a USB security key is used), it is temporarily encrypted using a randomly generated key. These measures make it harder for an adversary to find sensitive information in a memory dump.
This project is licensed under either of
at your option.

