cryptainer 2.2.0

tiny encrypted byte array container (Argon2id + AES256-GCM)
Documentation
# 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.

[![Crates.io](https://img.shields.io/crates/v/cryptainer.svg)](https://crates.io/crates/cryptainer)
[![Documentation](https://docs.rs/cryptainer/badge.svg)](https://docs.rs/cryptainer)
[![License](https://img.shields.io/crates/l/cryptainer.svg)](LICENSE)

## Features

- Password-based encryption with Argon2id
- AES-256-GCM authenticated encryption
- `no_std` support with `alloc`
- Optional derived-key zeroization
- Optional file helpers through `std`
- Optional bincode-backed struct encryption through `derive`

## Quick start

Add the crate with its standard-library defaults:

```toml
[dependencies]
cryptainer = "2.1"
```

### Encrypt bytes

```rust
use cryptainer::{decrypt_data, encrypt_data};

let mut rng = rand::rng();
let encrypted = encrypt_data("correct horse battery staple", b"hello world", &mut rng)?;
let plaintext = decrypt_data(&encrypted, "correct horse battery staple")?;
```

`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.

### Encrypt structs

Enable the `derive` feature:

```toml
[dependencies]
cryptainer = { version = "2.1", features = ["derive"] }
serde = { version = "1", features = ["derive"] }
```

Then derive `Cryptainer` alongside Serde:

```rust
use cryptainer::Cryptainer;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Cryptainer)]
struct Secret {
    message: String,
}

let mut rng = rand::rng();
let secret = Secret { message: "hello world".into() };
let encrypted = secret.encrypt("password", &mut rng)?;
let decrypted = Secret::decrypt(&encrypted, "password")?;
```

The derive generates `encrypt` and `decrypt` methods. Serialization uses
bincode 2; encrypted data is still authenticated by AES-GCM.

### Save and load files

```rust
use cryptainer::{decrypt_file, encrypt_data, load_file, save_file};

let mut rng = rand::rng();
let encrypted = encrypt_data("password", b"secret", &mut rng)?;
save_file("secret.stuff", &encrypted)?;
let plaintext = decrypt_file("secret.stuff", "password")?;
let encrypted_again = load_file("secret.stuff")?;
```

For derived structs, enable `derive` and use `load_value` to load, decrypt, and
deserialize a file in one step:

```rust
let secret: Secret = cryptainer::load_value("secret.stuff", "password")?;
```

## 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 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.

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>`
- `encrypt_value(value, password, rng) -> Result<CryptData, CryptError>` *(with `derive`)*
- `decrypt_value(data, password) -> Result<T, CryptError>` *(with `derive`)*
- `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)*
- `load_value(file_path, password) -> Result<T, CryptError>` *(std + derive)*

## Features

- `std` (default): enables file I/O and standard library integration
- `zeroize` (default): zeroizes derived keys and temporary serialized plaintext
  buffers where supported
- `derive`: enables bincode-backed struct encryption and the `Cryptainer` derive

## License

MIT