Rust port of iron-webcrypto — sealed, encrypted, and authenticated tokens using the Fe26.2 format.
Tokens produced by this library are wire-compatible with the JavaScript iron-webcrypto (and the original @hapi/iron) library.
seal serializes a value to JSON, encrypts it with AES-256-CBC (key derived via PBKDF2-SHA1), then appends an HMAC-SHA256 signature. The result is a self-contained string that can be safely stored in cookies or passed over untrusted channels.
unseal verifies the HMAC before decrypting, so tampering is detected before any data is processed.
Fe26.2*{id}*{encSalt}*{iv}*{encrypted}*{expiration}*{hmacSalt}*{hmac}
encSalt/hmacSalt— hex-encoded random PBKDF2 saltsiv/encrypted/hmac— base64url (no padding)
use iron_webcrypto_rs::{seal, unseal, Password, SealOptions};
use serde_json::json;
let opts = SealOptions::default();
let password = Password::from("a-secret-password-at-least-32-ch");
// Seal
let token = seal(&json!({"user": "alice"}), &password, &opts)?;
// Unseal
let value: serde_json::Value = unseal(&token, &password, &opts)?;
assert_eq!(value["user"], "alice");use std::time::Duration;
let opts = SealOptions {
ttl: 3_600_000, // 1 hour in milliseconds
..SealOptions::default()
};When the password is a &[u8] slice it is used directly as the key without PBKDF2 derivation. The slice must be at least 32 bytes.
let key = [0x42u8; 32];
let password = Password::from(key.as_slice());Use Password::WithId to embed a key ID in the token, and unseal_with_map to look it up on the way out.
use iron_webcrypto_rs::{Password, PasswordMap, PasswordValue, unseal_with_map, SealOptions};
let pw = Password::WithId {
id: "v2",
encryption: PasswordValue::Str("a-secret-password-at-least-32-ch"),
integrity: PasswordValue::Str("a-secret-password-at-least-32-ch"),
};
let token = seal(&json!("hello"), &pw, &SealOptions::default())?;
let mut map = PasswordMap::new();
map.insert("v2", pw);
let value: serde_json::Value = unseal_with_map(&token, &map, &SealOptions::default())?;| Step | Algorithm |
|---|---|
| Serialization | serde_json |
| Key derivation | PBKDF2-SHA1, 1 iteration, 256-bit random salt |
| Encryption | AES-256-CBC, PKCS7 padding |
| Integrity | HMAC-SHA256, constant-time verification |
| Encoding | salts → hex; IV, ciphertext, digest → base64url (no padding) |
Default options match the JavaScript library exactly and can be customized via SealOptions.
MIT