sealwd
sealwd provides small, focused primitives for handling secrets safely in Rust.
Designed specifically for server-side authentication systems, it enforces a strict separation between low-entropy user passwords and high-entropy machine-generated tokens. It handles memory zeroization, secure generation, policy validation, forward-compatible hashing, and optional encryption at rest.
Core Philosophy & Security Model
Passwords and tokens serve different purposes and require different cryptographic treatments:
- Passwords are low-entropy secrets provided by users. They are hashed using Argon2id (slow, memory-hard) to resist brute-force attacks.
- Tokens are high-entropy, fixed-length secrets generated by the system (e.g., session IDs, API keys). They are hashed using BLAKE3 (fast) with a server-side pepper. Using token hashing for passwords is mathematically insecure and intentionally unsupported by this crate.
Features
- Explicit Secret Types: Strongly typed
PasswordandToken<LEN>primitives. - Memory Safety: Secrets are wrapped in containers that automatically zeroize memory on drop.
- Password Policies: Configurable rules for generation and validation (length, character classes).
- Self-Describing Hashes: Binary serializable hashes (
PasswordHash,TokenHash) with embedded algorithm versions for forward compatibility. - Encryption at Rest (Optional): AEAD encryption (XChaCha20-Poly1305 or AES-256-GCM-SIV) via the
encryptionfeature. - Framework Integrations (Optional): Direct
BYTEAmappings for PostgreSQL viasqlx, and transparentserdeserialization.
Usage
Managing Passwords
use ;
// 1. Define a policy
let policy = with_sane_defaults;
// 2. Generate a secure random password satisfying the policy
let password = random.unwrap;
// 3. Hash the password for storage (uses Argon2id automatically)
let hash = password.to_default_hash.unwrap;
// 4. Verify a login attempt
assert!;
Managing High-Entropy Tokens
use Token;
// 1. Generate a 32-byte cryptographic token
let token = random.unwrap;
// 2. Export to URL-safe Base64 to send to the client
let encoded = token.to_base64;
// 3. Hash with a server-side pepper for database storage (uses BLAKE3)
let pepper = b"my-secret-server-pepper-value";
let token_hash = token.to_default_hash;
// 4. Store `token_hash.to_bytes()` in your database
Encryption at Rest (Requires encryption feature)
When storing secrets that must be reversible (e.g., external API keys), you can encrypt them before storage.
use ;
let token = random.unwrap;
let encryption_key = b"thisisa32bytekeyforrustcryptolib";
// Encrypt the token using XChaCha20-Poly1305
let encrypted_token = token.encrypt.unwrap;
// Decrypt back to a strongly-typed Token<16>
let decrypted_token = encrypted_token.decrypt.unwrap;
Feature Flags
encryption: Enables thecryptomodule, providingEncryptedPasswordandEncryptedTokenwrappers backed by AEAD ciphers.serde: Enables transparent serialization/deserialization for domain types.sqlx: Implementssqlx::Type,Encode, andDecodeallowing hashes and encrypted types to be used directly with database queries (maps toBYTEAin Postgres).
License
Apache-2.0