Skip to content

7eleven1717/iron-webcrypto-rs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

iron-webcrypto-rs

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.

How it works

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.

Token format

Fe26.2*{id}*{encSalt}*{iv}*{encrypted}*{expiration}*{hmacSalt}*{hmac}
  • encSalt / hmacSalt — hex-encoded random PBKDF2 salts
  • iv / encrypted / hmac — base64url (no padding)

Usage

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");

With TTL

use std::time::Duration;

let opts = SealOptions {
    ttl: 3_600_000, // 1 hour in milliseconds
    ..SealOptions::default()
};

Raw-bytes password

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());

Password rotation

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())?;

Cryptographic details

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.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages