enc_file
Password-based, authenticated file encryption with a small versioned header and Argon2id KDF. Ships as both a library and a CLI.
[!CAUTION] Security note: This project is neither audited nor reviewed. It protects data at rest but cannot defend a compromised host or advanced side channels. Use at your own risk. For important or sensitive information, use Veracrypt (or similar) instead.
Features
- Argon2id password KDF (per-file salt + stored parameters).
- AEAD: XChaCha20-Poly1305 (default) or AES-256-GCM-SIV.
- Compact binary header (magic, version, alg, KDF kind/params, salt, nonce, length).
- Optional ASCII armor for transport.
- Streaming mode for large files (constant memory; configurable
chunk_size
). - Use
secrecy
wrappers and zeroize buffers. - Compute a file hash and print it as hex.
- Usable as library and CLI.
Install
You can install enc-file in several ways:
From crates.io (requires Rust toolchain)
From GitHub Releases (prebuilt binaries)
- Visit the Releases page.
- Download the binary for your platform.
- Place it in a directory in your
PATH
.
From source
# from source
# binary
Add to a project as a library:
# Cargo.toml
[]
= "0.5.14"
CLI Usage
enc-file <SUBCOMMAND>
Subcommands:
enc Encrypt a file (use --stream for large files)
dec Decrypt a file
key Manage an encrypted key map
hash Compute a file hash and print it as hex
Encrypt
# Simple: prompts for password and outputs secret.pdf.enc in same directory
# Specify output filename, use AES-256-GCM-SIV and read password from file <PATH>
# Use shortcuts -i for --in and -o for --out
Options of interest:
--in
/-i
specify input file (required)--out
/-o
specify output file--alg
/-a
AEAD algorithm:xchacha
(default),aes
--stream
stream mode for large inputs--chunk-size <bytes>
set chunk size in streaming mode (default from library is 1 MiB)--armor
ASCII-armor output, attention: armored streaming is not available--force
/-f
overwrite output if file exists--password-file
/-p
<PATH>
read password from a file
Decrypt
# Use --force (or -f) to overwrite existing file
Hash
# Default blake3
# Specific algorithm (see below)
Key map (optional)
If you use the library’s key map helpers, the CLI can provide small helpers to init/save/load. Check enc-file key --help
for available subcommands.
Library Usage
Encrypt / Decrypt bytes
use ;
use SecretString;
let pw = new;
let opts = EncryptOptions ;
let ct = encrypt_bytes?;
let pt = decrypt_bytes?;
assert_eq!;
# Ok::
Encrypt / Decrypt files
use ;
use SecretString;
use Path;
let pw = new;
let opts = EncryptOptions ;
let out = encrypt_file?;
let back = decrypt_file?;
assert!;
# Ok::
Streaming encryption
use ;
use SecretString;
use Path;
let pw = new;
let opts = EncryptOptions ;
let out = encrypt_file_streaming?;
# Ok::
Chunk size: In streaming mode,
chunk_size = 0
uses the default (1 MiB). The maximum allowed isu32::MAX - 16
bytes, because each frame’s length is a 32-bit count of ciphertext bytes and the AEAD adds a 16-byte tag.
Hash helpers
Supported Hash Algorithms
Both the CLI and library support multiple hashing algorithms for files and byte slices:
Algorithm | CLI --alg value(s) |
Output length |
---|---|---|
BLAKE3 | blake3 |
32 bytes |
BLAKE2b-512 | blake2b |
64 bytes |
SHA-256 | sha256 |
32 bytes |
SHA-512 | sha512 |
64 bytes |
SHA3-256 | sha3-256 , sha3256 , sha3_256 |
32 bytes |
SHA3-512 | sha3-512 , sha3512 , sha3_512 |
64 bytes |
XXH3-64 | xxh3-64 , xxh364 |
8 bytes |
XXH3-128 | xxh3-128 , xxh3128 |
16 bytes |
CRC32 | crc32 |
4 bytes |
[!CAUTION] XXH3 and CRC32 are non-cryptographic! Use with care.
CLI Example:
# Compute SHA3-512 hash of a file
# Use XXH3-64 (fast, non-cryptographic)
Library Example:
use ;
let digest = hash_file?;
println!;
# Ok::
use ;
let digest = hash_bytes;
assert_eq!;
let file_digest = hash_file?;
println!;
# Ok::
Keyed BLAKE3 (MAC-style)
use hash_bytes_keyed_blake3;
let key = ;
let tag = hash_bytes_keyed_blake3;
assert_eq!;
# Ok::
Key map helpers
use ;
use SecretString;
use Path;
let mut km = new;
km.insert;
let pw = new;
let path = new;
save_keymap?;
let loaded = load_keymap?;
assert_eq!;
# Ok::
Error handling
All fallible APIs return Result<_, EncFileError>
. The error type is trait-based (thiserror::Error
) and covers all expected failures without panics.
Error variants:
Io(std::io::Error)
: I/O failures (file read/write issues)Crypto
: AEAD encryption/decryption failures (bad password, tampering)UnsupportedVersion(u16)
: File format version not supportedUnsupportedAead(u8)
: AEAD algorithm ID not supportedUnsupportedKdf(u8)
: Password KDF algorithm ID not supportedMalformed
: Corrupt or invalid file structureInvalid(&'static str)
: Invalid argument or operation (e.g. streaming with keymap)Serde(serde_cbor::Error)
: Serialization errors (CBOR encoding/decoding)
All errors are returned as Err(EncFileError)
; they never panic for expected failures.
See library and CLI tests for examples of error handling.
KDF defaults and bounds
This library uses Argon2id for password-based key derivation with hardened defaults:
- Time cost: 3 iterations (minimum)
- Memory cost: 64 MiB (minimum)
- Parallelism: min(4, number of CPU cores)
These parameters are enforced at the library level. The CLI uses compliant defaults automatically.
Streaming and armor
- Streaming mode provides constant memory usage for large files using chunked framing
- ASCII armor is ignored in streaming mode - only non-streaming payloads can be armored
- Maximum chunk size is
u32::MAX - 16
bytes due to 32-bit frame length + 16-byte AEAD tag
Compatibility policy
This library maintains backward compatibility for reading encrypted files across versions (beginning from 0.5). Backward-compatible format extensions (optional header fields) may be added between minor releases. Existing files remain decryptable by newer versions.
Tips
- Use streaming for large files to keep memory predictable.
- Consider
--armor
when moving ciphertexts through systems that mangle binaries. - For CLI automation, prefer
--password-file
over interactive prompts.
License
Licensed under either of
at your option.
Any contribution intentionally submitted for inclusion in this work shall be dual licensed as above, without any additional terms or conditions.
Note on names
The library crate is named enc_file
(snake_case), which is the name you use when importing it in Rust code:
use ;
The compiled CLI binary is named enc-file
(kebab-case), which is the name you use when invoking it from the shell:
This naming separation is intentional and follows common conventions.
Feedback & Issues
Feedback, bug reports, and pull requests are highly appreciated! Open an Issue or start a discussion.