first commit
This commit is contained in:
116
docs/security-stack/crypto/crypto-vault/src/argon2id/argon2id.md
Normal file
116
docs/security-stack/crypto/crypto-vault/src/argon2id/argon2id.md
Normal file
@@ -0,0 +1,116 @@
|
||||
# Argon2id wrapper
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
## Purpose
|
||||
|
||||
`argon2id.ts` is the OWASP-grade Argon2id derivation entry point for
|
||||
`@suaveplan/crypto-vault`. It wraps `@suaveplan/crypto-hash`'s primitive
|
||||
`argon2id` with two enterprise concerns the primitive itself does not
|
||||
enforce: an OWASP-safe parameter floor (memoryKB ≥ 64 MiB, iterations ≥ 3,
|
||||
parallelism ≥ 1) and a hard ceiling (memoryKB ≤ 1 GiB, outputLength ≤ 4 KiB)
|
||||
that prevents accidental denial-of-service from misconfigured callers.
|
||||
|
||||
## Features
|
||||
|
||||
- `assertSafeArgon2idParams(params)` — pure validator usable in tests, in
|
||||
config validation, and as a precondition for any Argon2id call.
|
||||
- `deriveKeyWithArgon2id(password, salt, params?, options?)` — full
|
||||
derivation pipeline with telemetry recording and structured errors.
|
||||
- `DEFAULT_ARGON2ID_PARAMS` — frozen `{ memoryKB: 65536, iterations: 3,
|
||||
parallelism: 4, outputLength: 32 }` constant.
|
||||
- `OWASP_MIN_*` and `ARGON2ID_MAX_*` exported constants for callers that
|
||||
build their own parameter UI.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import {
|
||||
DEFAULT_ARGON2ID_PARAMS,
|
||||
deriveKeyWithArgon2id,
|
||||
} from "@suaveplan/crypto-vault/argon2id/argon2id";
|
||||
|
||||
const password = new TextEncoder().encode("correct horse battery staple");
|
||||
const salt = crypto.getRandomValues(new Uint8Array(16));
|
||||
const key = await deriveKeyWithArgon2id(password, salt, DEFAULT_ARGON2ID_PARAMS);
|
||||
console.log(key.length); // 32
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import {
|
||||
assertSafeArgon2idParams,
|
||||
deriveKeyWithArgon2id,
|
||||
} from "@suaveplan/crypto-vault/argon2id/argon2id";
|
||||
import type { Argon2idParams } from "@suaveplan/crypto-vault/types";
|
||||
|
||||
// Stronger profile for highly sensitive accounts.
|
||||
const strict: Argon2idParams = {
|
||||
memoryKB: 131_072, // 128 MiB
|
||||
iterations: 4,
|
||||
parallelism: 4,
|
||||
outputLength: 64,
|
||||
};
|
||||
assertSafeArgon2idParams(strict); // throws if any cell breaks the bands
|
||||
|
||||
const password = new TextEncoder().encode("super-strong-passphrase");
|
||||
const salt = crypto.getRandomValues(new Uint8Array(16));
|
||||
const key = await deriveKeyWithArgon2id(password, salt, strict, {
|
||||
clock: () => 0, // deterministic telemetry timestamps for tests
|
||||
});
|
||||
console.log(key.length); // 64
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `deriveKeyWithArgon2id(password, salt, params?, options?)`
|
||||
|
||||
- `password: Uint8Array` — must be non-empty.
|
||||
- `salt: Uint8Array` — must be non-empty (16+ bytes recommended).
|
||||
- `params: Argon2idParams = DEFAULT_ARGON2ID_PARAMS` — validated through
|
||||
`assertSafeArgon2idParams`.
|
||||
- `options.clock?: () => number` — wall-clock source for the duration
|
||||
histogram.
|
||||
|
||||
Returns `Promise<Uint8Array>` of length `params.outputLength`.
|
||||
|
||||
Throws `CryptoVaultError`:
|
||||
|
||||
- `ARGON2ID.INVALID_INPUT` for empty `password` or `salt`.
|
||||
- `ARGON2ID.UNSAFE_PARAMETERS` for parameters outside the OWASP / hard-cap
|
||||
bands.
|
||||
|
||||
### `assertSafeArgon2idParams(params)`
|
||||
|
||||
Throws `CryptoVaultError(ARGON2ID.UNSAFE_PARAMETERS)` when any of these
|
||||
conditions are violated:
|
||||
|
||||
- `memoryKB` integer in `[OWASP_MIN_MEMORY_KB, ARGON2ID_MAX_MEMORY_KB]`.
|
||||
- `iterations` integer ≥ `OWASP_MIN_ITERATIONS`.
|
||||
- `parallelism` integer ≥ `OWASP_MIN_PARALLELISM`.
|
||||
- `outputLength` integer in `(0, ARGON2ID_MAX_OUTPUT_LENGTH]`.
|
||||
|
||||
### Constants
|
||||
|
||||
- `OWASP_MIN_MEMORY_KB = 65_536`
|
||||
- `OWASP_MIN_ITERATIONS = 3`
|
||||
- `OWASP_MIN_PARALLELISM = 1`
|
||||
- `ARGON2ID_MAX_MEMORY_KB = 1_048_576`
|
||||
- `ARGON2ID_MAX_OUTPUT_LENGTH = 4_096`
|
||||
- `DEFAULT_ARGON2ID_PARAMS` — frozen object.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- The underlying primitive is sync (noble's `@noble/hashes/argon2`); the
|
||||
wrapper exposes `Promise<Uint8Array>` to keep the public API stable
|
||||
against future native or worker-backed implementations.
|
||||
- The OWASP minimums encode the November 2024 password storage cheat sheet
|
||||
guidance for Argon2id (m=64MiB, t=3, p=1+).
|
||||
- The hard cap on memory cost (1 GiB) and output length (4 KiB) defends
|
||||
against caller bugs and denial-of-service-by-misconfiguration. A caller
|
||||
that legitimately needs more should open a follow-up change rather than
|
||||
bypass the guard.
|
||||
- Telemetry timing comes from the injected (or default) clock, not
|
||||
`performance.now()`; this keeps the histogram reproducible under tests.
|
||||
Reference in New Issue
Block a user