Skip to main content

Crate hefesto

Crate hefesto 

Source
Expand description

§hefesto

Double envelope encryption for multi-tenant applications.

Each value is encrypted with two independent keys — a per-tenant key and a global master key — so a breach of either key alone does not expose plaintext. The outer layer also binds the ciphertext to the tenant via AEAD additional data, preventing cross-tenant replay.

§Security model

plaintext
  └─▶ AES-256-GCM(key = Argon2id(tenant_key, salt₁))          ← inner layer
        └─▶ AES-256-GCM(key = Argon2id(master_key, salt₂),
                         aad = tenant_key)                      ← outer layer
              └─▶ base64(version ‖ salt₁ ‖ salt₂ ‖ ciphertext)
PropertyMechanism
ConfidentialityAES-256-GCM (two layers)
Key hardeningArgon2id (64 MiB, 3 iterations)
Non-determinism96-bit random nonce per encryption
Tenant isolationtenant_key used as AAD on outer layer
Memory safetyzeroize zeroes key material on drop

§Quick start

use hefesto::{encrypt, decrypt, hash_password, verify_password, hash_for_lookup};

let tenant_key = "per_tenant_secret_key_32bytes___";
let master_key = "global_master_key_32bytes_______";

// Encrypt and decrypt a sensitive value
let ciphertext = encrypt("user@example.com", tenant_key, master_key).unwrap();
let plaintext  = decrypt(&ciphertext, tenant_key, master_key).unwrap();
assert_eq!(plaintext, "user@example.com");

// Hash a password for storage (Argon2id PHC string)
let hash = hash_password("s3cr3t").unwrap();
assert!(verify_password("s3cr3t", &hash));

// Deterministic lookup token — same value + same tenant_key → same hash
let token = hash_for_lookup("user@example.com", tenant_key).unwrap();
assert_eq!(token, hash_for_lookup("user@example.com", tenant_key).unwrap());

§Minimum key length

Both tenant_key and master_key must be at least 16 bytes. Shorter keys are rejected with HefestoError::InvalidKey. Keys of 32+ bytes are strongly recommended in production.

§Payload versioning

The ciphertext payload begins with a version byte (0x02). Payloads from hefesto v1.x (version byte 0x01) are not compatible and will be rejected.

§Feature flags

This crate has no optional features. All primitives are always compiled.

Enums§

HefestoError
Errors returned by hefesto operations.

Functions§

decrypt
Decrypts a ciphertext produced by encrypt.
encrypt
Encrypts value using double envelope encryption.
hash_for_lookup
Computes a deterministic, tenant-scoped lookup token for a plaintext value.
hash_password
Hashes a password using Argon2id and returns a PHC-format string.
verify_password
Verifies a password against an Argon2id PHC hash produced by hash_password.