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
- Command-line usage
- Desktop app
- Files and folders
- Troubleshooting
- Security
- Compatibility
- Build from source
- Technical reference
- License and credits
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:
The installed command is ferrocrypt.
Add the Rust library
Requires Rust 1.87 or later:
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
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:
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:
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:
Encrypt with the public key, then decrypt with the matching 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:
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.
-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.txtbecomessecret.fcr; a folder namedmy.photosbecomesmy.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-asor 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:
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:
Then, from the repository root:
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
# Debian/Ubuntu: target/release/bundle/deb/*.deb; cargo-bundle needs OpenSSL
# Windows: target\wix\*.msi; also requires WiX Toolset 3
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).