cryptainer
Small, password-based authenticated encryption for Rust.
Encrypt byte slices or Serde-compatible structs with Argon2id and
AES-256-GCM, then decrypt them with a simple, typed API. cryptainer is
no_std-friendly and keeps file I/O optional.
Features
- Password-based encryption with Argon2id
- AES-256-GCM authenticated encryption
no_stdsupport withalloc- Optional derived-key zeroization
- Pre-derived 256-bit key APIs
- Optional file helpers through
std - Optional bincode-backed struct encryption through
derive
Quick start
Add the crate with its standard-library defaults:
[]
= "2.3"
= "0.10"
Encrypt bytes
use ;
let mut rng = rng;
let encrypted = encrypt_data?;
let plaintext = decrypt_data?;
encrypt_data returns a CryptData value containing the salt, nonce, and
ciphertext. Keep it together until you are ready to persist it or decrypt it.
For applications that already manage key derivation, derive a 256-bit key once using a fresh, randomly generated salt, then use the key-based APIs. The salt is not secret, but retain it with the encrypted data if the key must later be re-derived:
use ;
use Rng;
let mut rng = rng;
let mut salt = ;
rng.fill_bytes;
let key = derive_key?;
let encrypted = encrypt_with_key?;
let plaintext = decrypt_with_key?;
Encrypt structs
Enable the derive feature:
[]
= { = "2.3", = ["derive"] }
= "0.10"
= { = "1", = ["derive"] }
Then derive Cryptainer alongside Serde:
use Cryptainer;
use ;
let mut rng = rng;
let secret = Secret ;
let encrypted = secret.encrypt?;
let decrypted = decrypt?;
The derive generates password-based and pre-derived-key methods:
encrypt, decrypt, encrypt_with_key, decrypt_with_key, decrypt_bytes,
and decrypt_bytes_with_key. Serialization uses bincode 2; encrypted data is
still authenticated by AES-GCM.
Save and load files
use ;
let mut rng = rng;
let encrypted = encrypt_data?;
save_file?;
let plaintext = decrypt_file?;
let encrypted_again = load_file?;
For derived structs, enable derive and use load_value to load, decrypt, and
deserialize a file in one step:
let secret: Secret = load_value?;
Format and security
Encrypted output is stored as:
salt (16 bytes) || nonce (12 bytes) || ciphertext
The ciphertext includes the AES-GCM authentication tag. Passwords are processed
with Argon2id using 19,456 KiB of memory, 2 iterations, 1 lane, version 0x13,
and a 32-byte output to derive a 256-bit encryption key. A fresh salt and nonce
are generated for every call to encrypt_data; callers must provide a
cryptographically secure RNG. Key-based encryption still requires a 16-byte
salt because the salt is retained in the compatible wire format.
When enabled, the zeroize feature clears derived keys and temporary
serialization buffers when they are dropped. It cannot clear passwords,
caller-owned plaintext, decrypted return values, or encrypted data retained
for persistence.
cryptainer does not provide password storage, password strength checking, key
rotation, or secure password transport. Applications should handle those
concerns separately.
API at a glance
encrypt_data(password, plaintext, rng) -> Result<CryptData, CryptError>decrypt_data(data, password) -> Result<Vec<u8>, CryptError>decrypt_bytes(data, password) -> Result<Vec<u8>, CryptError>derive_key(password, salt) -> Result<KeyBuffer, CryptError>encrypt_with_key(key, salt, plaintext, rng) -> Result<CryptData, CryptError>decrypt_with_key(data, key) -> Result<Vec<u8>, CryptError>decrypt_bytes_with_key(data, key) -> Result<Vec<u8>, CryptError>encrypt_value(value, password, rng) -> Result<CryptData, CryptError>(withderive)decrypt_value(data, password) -> Result<T, CryptError>(withderive)encrypt_value_with_key(value, key, salt, rng) -> Result<CryptData, CryptError>(withderive)decrypt_value_with_key(data, key) -> Result<T, CryptError>(withderive)save_file(file_path, data) -> Result<(), CryptError>(std only)load_file(file_path) -> Result<CryptData, CryptError>(std only)decrypt_file(file_path, password) -> Result<Vec<u8>, CryptError>(std only)decrypt_file_with_key(file_path, key) -> Result<Vec<u8>, CryptError>(std only)load_value(file_path, password) -> Result<T, CryptError>(std + derive)load_value_with_key(file_path, key) -> Result<T, CryptError>(std + derive)
Invalid salts, nonces, ciphertexts, malformed serialized data, authentication
failures, serialization failures, and file I/O failures are returned through
CryptError. Matching on this enum should include a wildcard arm so future
error variants can be added without breaking downstream code.
Features
std(default): enables file I/O and standard library integrationzeroize(default): zeroizes derived keys and temporary serialized plaintext buffers where supportedderive: enables bincode-backed struct encryption and theCryptainerderive
License
MIT