ferrocrypt 0.3.0

Recipient-oriented file and directory encryption: passphrase (Argon2id) and X25519 public-key recipients, XChaCha20-Poly1305 STREAM payloads, HKDF-SHA3-256 / HMAC-SHA3-256 key derivation and authentication.
Documentation

Build and tests crate: ferrocrypt API documentation Library minimum Rust version crate: ferrocrypt-cli

FerroCrypt encrypts files and folders into a single .fcr file. It is available as a desktop app, a command-line tool, and a Rust library for Linux, macOS, and Windows.

Choose how to protect your data:

  • Password: use the same password to encrypt and decrypt. The command line and library call this a passphrase.
  • Key pair: encrypt with a recipient's public key. Decryption requires the matching private key and its password. The command line and library can encrypt one file for several recipients; any one of them can decrypt it.

Encryption leaves the original files in place. File contents are processed in chunks, so an entire file does not need to fit in memory. Password processing uses 1 GiB of memory by default, including when creating or unlocking a private key.

Contents

Installation

Download the package for your system from GitHub Releases.

System Command-line tool Desktop app
macOS, Intel or Apple silicon .tar.gz .zip containing FerroCrypt.app
Linux, 64-bit Intel/AMD .tar.gz, gnu or musl .deb for Debian/Ubuntu
Linux, 64-bit ARM .tar.gz, musl Build from source
Windows, 64-bit Intel/AMD .zip .msi installer

Extract a command-line download and place ferrocrypt (ferrocrypt.exe on Windows) in a folder on your PATH. The Linux gnu build uses the system's C library and needs a recent version of it. The musl builds need no shared libraries, so they also work on older distributions, Alpine, and minimal container images.

On macOS, extract the desktop app and move it to Applications. Neither the app nor the command-line tool is notarized by Apple, so macOS may block each the first time you run it. If it does, open System Settings → Privacy & Security, click Open Anyway, then confirm Open. See Apple's instructions.

Install the command-line tool with Cargo

Requires Rust 1.89 or later:

cargo install ferrocrypt-cli@0.3.0

The installed command is ferrocrypt.

Add the Rust library

Requires Rust 1.87 or later:

cargo add ferrocrypt@0.3.0

The library handles files, folders, output naming, and encryption through Encryptor and Decryptor. It also provides key generation, public-key fingerprints, progress callbacks, configurable resource limits, and structured CryptoError values. See the API documentation and examples for password and public-key workflows.

Library operations are blocking. In an asynchronous application, run them on a blocking worker. Services processing untrusted input also need explicit limits, bounded concurrency, and a private work folder for each operation; see the deployment requirements.

Command-line usage

Command Alias Purpose
encrypt enc Encrypt a file or folder
decrypt dec Decrypt an encrypted file
keygen gen Create a public/private key pair
fingerprint fp Display a public key's fingerprint

Use ferrocrypt --help or ferrocrypt <command> --help for full options.

Create the output folders before encrypting or decrypting; only key generation creates its folder if needed. FerroCrypt refuses an output name that already exists. The examples below assume secret.txt and the folders encrypted and decrypted already exist.

Encrypt and decrypt with a password

ferrocrypt encrypt -i secret.txt -o ./encrypted
ferrocrypt decrypt -i ./encrypted/secret.fcr -o ./decrypted

Encryption asks for a passphrase and confirmation; decryption asks for the same passphrase. Input is hidden. The result is encrypted/secret.fcr, and decryption restores decrypted/secret.txt.

For a folder, use its path as the input. To choose the encrypted filename, use --save-as instead of --output-dir:

ferrocrypt encrypt -i ./photos -s ./encrypted/photos-backup.fcr

Password encryption is the default when no public key or recipient string is given. --passphrase (-p) selects it explicitly; the flag does not take a password value.

Encrypt and decrypt with a key pair

Create a key pair and choose a password for the private key:

ferrocrypt keygen -o ./keys

This creates public.key and a password-protected private.key. Share the public key with anyone who needs to encrypt files for you. Keep the private key and its password secret, and keep a backup of both.

Before encrypting for someone else, compare their public-key fingerprint over a trusted channel, such as a phone call. keygen prints the fingerprint of each new key pair; for an existing public key file, run:

ferrocrypt fingerprint ./keys/public.key

Encrypt with the public key, then decrypt with the matching private key:

ferrocrypt encrypt -i secret.txt -o ./encrypted -k ./keys/public.key
ferrocrypt decrypt -i ./encrypted/secret.fcr -o ./decrypted -K ./keys/private.key

-k selects a public key; -K selects a private key. Public-key encryption needs no password. Decryption prompts for the private key's password. It detects the encryption method from the file contents, even if the file was renamed.

To let several recipients decrypt the same file, repeat -k:

ferrocrypt encrypt -i secret.txt -s ./encrypted/shared.fcr \
  -k ./alice/public.key -k ./bob/public.key

A public key can also be shared as a lowercase fcr1... recipient string, which is the text stored in public.key. Use -r with the full string:

# Replace fcr1... with the recipient's complete string.
ferrocrypt encrypt -i secret.txt -s ./encrypted/recipient.fcr -r fcr1...

-r and -k can be repeated and combined. Password and public-key encryption cannot be combined in one file.

Interactive mode and scripts

Run ferrocrypt without arguments to open an interactive prompt. Enter commands without the ferrocrypt prefix:

ferrocrypt> encrypt -i secret.txt -o ./encrypted
ferrocrypt> quit

quit, exit, or Ctrl-D closes the prompt. Ctrl-C at the prompt cancels the current line.

For scripts, supply the password through FERROCRYPT_PASSPHRASE. It takes precedence over the prompt and skips confirmation. Passwords are never accepted as command-line arguments or read from piped input. Without a terminal or this variable, a command that needs a password fails instead of waiting for input. Environment variables may be readable by other processes running as the same user; prefer the hidden prompt when possible.

If an input already looks like a FerroCrypt file, encrypt asks for confirmation in a terminal and refuses in a script. Use --allow-double-encrypt to permit it.

Common options

Option Commands Meaning
-i, --input encrypt, decrypt File or folder to encrypt; encrypted file to decrypt
-o, --output-dir encrypt, decrypt, keygen Destination folder
-s, --save-as encrypt Exact output file path; replaces -o
-p, --passphrase encrypt Select password encryption explicitly
-k, --public-key encrypt Public key file; repeatable
-r, --recipient encrypt Public recipient string; repeatable
-K, --private-key decrypt Private key file for public-key decryption
--allow-double-encrypt encrypt Allow encrypting an already encrypted file
--keep-partial decrypt Keep incomplete output after an error for inspection or recovery

fingerprint takes the public key path directly, without -i.

Resource limits

Archive limits stop a damaged or hostile file from using more memory or disk than expected. Encryption and decryption apply the same limits, including to single files. If your data exceeds a default, raise that limit on both sides.

Option What it limits Default
--max-archive-entries Files and folders, including the root 250,000
--max-archive-size Combined file contents, in MiB 65,536 (64 GiB)
--max-archive-path-depth Path components, including the root 64
--max-archive-path-bytes Each archived path, in UTF-8 bytes 4,096
--max-archive-manifest The stored list of paths and metadata, in MiB 64

Decryption also limits the password-processing cost requested by an encrypted file or private key. Only raise these limits for a trusted source and within your machine's resources.

Option What it limits Default
--max-kdf-memory Argon2id memory, in MiB 1,024 (1 GiB)
--max-kdf-time-cost Argon2id passes 12
--max-kdf-lanes Argon2id parallelism 8
--max-kdf-work Memory in KiB multiplied by passes 4,194,304

These four flags apply only to decrypt. Raising the memory limit does not raise the combined work limit. Lowering a limit does not make a file cheaper to decrypt; it makes FerroCrypt refuse a file that exceeds it.

Desktop app

Select a file or folder, choose the destination, and use one of the two tabs:

  • Password: encrypt and decrypt with a password.
  • Key pair: encrypt with a public key or decrypt with a private key and its password. Create key pair generates keys within the app.

Selecting an encrypted file switches to the appropriate decryption mode. For encryption, the app suggests an output filename; Choose beside the output opens a Save As dialog. Selected key files are checked, and public-key fingerprints are displayed for verification. A strength indicator helps when choosing a password for encryption or a new private key.

The app encrypts for one public-key recipient at a time. It can decrypt a file made for several recipients with any matching private key. Use the command line or library to encrypt for several recipients, adjust resource limits, or retain incomplete output after an error.

Files and folders

  • Names: a file named secret.txt becomes secret.fcr; a folder named my.photos becomes my.photos.fcr. Decryption restores the original name stored inside the file, regardless of the encrypted filename.
  • Contents: regular files, empty folders, and folder structure are preserved. Hard links are stored as separate files. Data is not compressed.
  • Permissions and metadata: Unix read, write, and execute permissions are stored and restored on Unix. Ownership, timestamps, access-control lists, extended attributes, special permission bits, and other platform metadata are not preserved. Windows does not restore Unix permissions.
  • Unsupported entries: symbolic links, Windows junctions and other reparse points, devices, pipes, and sockets are refused.
  • Portable names: each file or folder name must be valid UTF-8 text, with at most 244 bytes. Windows-reserved names and characters, trailing dots or spaces, and certain invisible control characters are refused on every platform. Duplicate paths, names differing only by ASCII letter case, and equivalent Unicode spellings are also refused. See the full naming rules.

FerroCrypt is intended for file storage and transfer, not a complete system backup. Keep source files unchanged while encryption runs; it does not take a point-in-time snapshot.

Troubleshooting

Errors distinguish credential problems, damaged files, unsupported data, and resource limits. A wrong password and some forms of file modification cannot be distinguished.

Message or problem What to check
Private key unlock failed Check the private key's password and whether the key file is intact.
wrong passphrase or modified file Check the file's password; if it is correct, try an intact copy of the encrypted file.
no matching recipient or modified file Use a private key matching one of the intended recipients; also check the encrypted file.
file header was modified or corrupted / file data was modified or corrupted Integrity verification failed. Obtain an intact copy.
Not a FerroCrypt file, too short, truncated, malformed, or unexpected trailing data Check the input file and transfer, and whether it came from an older release.
Unsupported version, recipient, or feature Follow the message's guidance. A newer feature may need a newer release; old-format data needs migration.
Passphrase or archive limit exceeded Raise the matching resource limit only for data from a trusted source.
Header, recipient, or key-file limit exceeded These additional limits are configurable through the library's HeaderReadLimits and KeyReadLimits.
already exists Choose another destination or move the conflicting entry after checking it.
No such file or directory Create the output folder first, or the folder of a --save-as path.

Incomplete output

Decryption writes a temporary plaintext file or folder named <original-name>.incomplete. It receives its final name only after all encrypted content and archive checks pass.

By default, FerroCrypt removes its temporary output after a decryption error. If removal fails or cannot be confirmed, the error names the working path and says whether plaintext may remain. If decryption is interrupted, for example with Ctrl-C, by closing the app, or by a power loss, the temporary output may remain on disk and contain plaintext. A previous .incomplete entry is never reused or automatically deleted; check it and move or remove it before retrying.

Encryption and key generation write to hidden temporary files named .ferrocrypt-… and give a file its final name only once it is complete. An interrupted run can leave such a file behind; it holds no plaintext and can be deleted.

decrypt --keep-partial keeps incomplete output for recovery or inspection. Recovered parts may pass integrity checks even when an attacker has deliberately cut off the rest of the file. Do not treat a partial result as a successful decryption. Library callers can use IncompleteOutputPolicy::RetainOnError.

A final filesystem check can fail after complete output has been written. Such an error says that the output is complete; confirmed output is preserved, and may remain under its final name, a moved name, or an additional hard link. Read the full error before retrying. An error does not always mean that nothing was written.

Security

FerroCrypt has not undergone an independent third-party security audit. The security policy covers audit status, known limitations, and private vulnerability reporting. The threat model defines the security guarantees and their assumptions.

  • Credentials: use a strong password and protect your private keys. FerroCrypt has no password reset. Public-key fingerprints need verification through a trusted channel; a valid public key alone does not establish its owner's identity.
  • Integrity and identity: file headers are verified before decryption releases any plaintext, and file contents are checked as they are decrypted. This detects modification but does not prove who sent a file or whether it is the latest copy. Use separate signatures or version records when needed.
  • Visible information: file contents, internal names, folder structure, and per-file sizes are encrypted. Total encrypted size, recipient count, and the fact that a file is a FerroCrypt file remain visible. The default output name can also reveal the source name; choose another with --save-as or the desktop Save As dialog if needed.
  • Local access: encryption cannot protect data from someone who controls your running system. The desktop toolkit may leave password text in memory until the app exits; the CLI's hidden prompt clears its own password buffers. See the memory and environment limitations.
  • Output folders: decryption writes only inside the chosen output folder and refuses unsafe paths stored in the encrypted file. Choose an output folder that untrusted processes cannot modify, including its parent folders. Existing output entries are refused. On Windows, folder decryption has a brief final-rename gap in which another process could create an entry that gets replaced; use a private output folder.
  • Filesystems: full filesystem protections apply on Linux with ext4, macOS with APFS, and Windows with NTFS. Other filesystems, such as exFAT or network filesystems, may refuse operations or provide weaker permission, concurrent-change, and power-loss protections. The encryption and file-format checks still apply.

Compatibility

The format compatibility promise begins with stable 0.3.0: files and key pairs written by that release remain readable by every later release. Files from alpha, beta, release-candidate, or untagged development builds are outside that promise. See the format compatibility policy.

Releases before the 0.3.0 series use incompatible file and key formats. Decrypt older data with the release that created it, then re-encrypt it with the current release. See the changelog for migration and release details.

The Rust API is pre-1.0: patch releases such as 0.3.x preserve it; a minor release such as 0.4.0 may change it. Stored-file compatibility is a separate promise. The minimum Rust versions stated above are checked in CI and may rise in a later release when a dependency or language change requires it.

Build from source

From a repository checkout, build the command-line tool with Rust 1.89 or later:

cargo build --release

The binary is target/release/ferrocrypt, or target\release\ferrocrypt.exe on Windows.

The desktop app builds separately. Use a current stable Rust toolchain. On Debian/Ubuntu, install the system packages it needs first:

sudo apt install libfontconfig-dev libfreetype-dev libxcb-shape0-dev \
                 libxcb-xfixes0-dev libxkbcommon-dev libwayland-dev

Then, from the repository root:

cd ferrocrypt-desktop
cargo build --release

The binary is ferrocrypt-desktop/target/release/ferrocrypt-desktop, with .exe on Windows. It does not need other files from the repository at runtime.

Run the commands for your platform from ferrocrypt-desktop. The packaging tool also builds the binary.

# macOS: target/release/bundle/osx/FerroCrypt.app
cargo install cargo-bundle --version 0.11.0 --locked
cargo bundle --release --format osx
codesign --force --deep --sign - target/release/bundle/osx/FerroCrypt.app

# Debian/Ubuntu: target/release/bundle/deb/*.deb; cargo-bundle needs OpenSSL
sudo apt install libssl-dev
cargo install cargo-bundle --version 0.11.0 --locked
cargo bundle --release --format deb
sudo apt install ./target/release/bundle/deb/*.deb

# Windows: target\wix\*.msi; also requires WiX Toolset 3
cargo install cargo-wix
cargo wix

The macOS bundle can be opened from Finder. The Debian package installs the app and adds it to the application menu.

See Contributing for the repository layout and development checks.

Technical reference

The cryptographic implementation is written in Rust and does not depend on OpenSSL. The library forbids unsafe code.

Purpose Algorithm or format
File encryption XChaCha20-Poly1305 STREAM-BE32, in 64 KiB chunks
Password processing Argon2id
Public-key agreement X25519
Key derivation HKDF-SHA3-256
Header integrity HMAC-SHA3-256
Public-key fingerprints SHA3-256
Public recipient strings Bech32 with the fcr prefix
Files and folders inside the encrypted payload FerroCrypt Archive (FCA)
  • File format: encrypted files, key files, archive rules, and compatibility.
  • Library structure: API boundaries and implementation.
  • Format test vectors: fixed files and expected results for checking an implementation against the format.

License and credits

Licensed under GPL-3.0-only.

The desktop app uses Slint. Password strength scoring is adapted from Proton Pass (GPLv3).

forthebadge