Skip to main content

Module crypt

Module crypt 

Source
Expand description

Encryption and signing under the application key.

One master key (app.key, 32 bytes, base64) with an id, plus previous keys kept for reading data written under them. Every operation names a purpose; a subkey is derived per purpose, so a value encrypted for one purpose never decrypts under another and a token signed for one flow never verifies in another.

ⓘ
let sealed = crypt.encrypt("api-secret", b"table.column.42", b"hunter2")?;
let plain = crypt.decrypt("api-secret", b"table.column.42", &sealed)?;
let token = crypt.token("password-reset", b"user:7", Duration::from_secs(3600));
let payload = crypt.check_token("password-reset", &token)?;

AEAD is XChaCha20-Poly1305 with a random 24-byte nonce; signing is keyed BLAKE3. A sealed value is [version][key id][nonce][ciphertext] and a signature [version][key id][tag], both base64url without padding.

Modules§

migrations
The crypt schema, as a portable one-file migration.

Structs§

Crypt
The application’s keys: the current one writes, every one reads.
CryptModule
The module that owns the registry table, listed among an application’s built-ins.
MasterKey
A 32-byte master secret with its id.
Rotated
What a rotation did: rows re-sealed under the current key, rows already under it, and rows that would not open (left as they were).

Enums§

CryptError
What went wrong sealing, opening or checking.

Constants§

FIELD_PURPOSE
The purpose a sealed form field uses; its AAD is the field’s name.
MASK
The text a sealed field shows in place of its value; submitting it back means “unchanged”.

Functions§

register_column
Records that table.column holds values sealed for purpose (with the column’s name as AAD), so a rotation finds them. Idempotent.
registered_columns
Every registered sealed column: (table, column, purpose).
rotate
Re-seals every registered column’s values under the current key: a value sealed under a previous key is opened and sealed again; one already under the current key is left; one that does not open is counted and left.