Files
skills/docs/security-stack/crypto/crypto-sodium/src/primitives/crypto-pwhash/crypto-pwhash.md
2026-05-29 08:20:56 +01:00

3.9 KiB

primitives/crypto-pwhash

(no submodules)

Purpose

cryptoPwhashStr and cryptoPwhashStrVerify expose libsodium's Argon2id password hashing via crypto_pwhash_str and crypto_pwhash_str_verify. Argon2id is the winner of the Password Hashing Competition (2015) and the recommended algorithm for password storage by OWASP and NIST SP 800-63B.

The encoded hash string includes the algorithm identifier, salt, and cost parameters — it is self-contained and safe to store directly in a database. This eliminates a class of bugs where the salt or parameters are stored separately and can become desynchronised.

Features

  • Argon2id password hashing via crypto_pwhash_str — salt generated internally.
  • Self-contained encoded output (≈97 chars) — includes algorithm, salt, opsLimit, memLimit.
  • Constant-time verification via crypto_pwhash_str_verify.
  • Configurable opsLimit and memLimit — defaults to OPSLIMIT_INTERACTIVE / MEMLIMIT_INTERACTIVE.
  • Async — calls sodiumReady() internally.
  • cryptoPwhashStrVerify returns false on any failure, never throws.

Usage: Basic Example

import { cryptoPwhashStr, cryptoPwhashStrVerify } from "@suaveplan/crypto-sodium/primitives/pwhash";

const password = new TextEncoder().encode("user-password-here");
const hash = await cryptoPwhashStr(password);

// Store `hash` in your database. Later, at login:
const valid = await cryptoPwhashStrVerify(hash, password);
console.log(valid); // true

Usage: Advanced Example

Higher-security settings for sensitive credential storage:

import { cryptoPwhashStr, cryptoPwhashStrVerify } from "@suaveplan/crypto-sodium/primitives/pwhash";

const password = new TextEncoder().encode("admin-master-password");

// Sensitive account — use MODERATE or SENSITIVE preset values
// crypto_pwhash_OPSLIMIT_MODERATE = 3, MEMLIMIT_MODERATE = 268435456 (256 MiB)
const hash = await cryptoPwhashStr(password, {
  opsLimit: 3,
  memLimit: 268_435_456,
});

// Verification automatically reads cost parameters from the hash string
const ok = await cryptoPwhashStrVerify(hash, password);

// Password rehashing: if ok but hash uses lower-cost params, rehash
// (the encoded string embeds the params so you can detect this)

API Reference

cryptoPwhashStr(password, opts?): Promise<string>

Hashes password with Argon2id.

Parameters:

  • password: Uint8Array — Raw password bytes.
  • opts.opsLimit?: number — CPU/iteration cost. Default: crypto_pwhash_OPSLIMIT_INTERACTIVE.
  • opts.memLimit?: number — Memory cost in bytes. Default: crypto_pwhash_MEMLIMIT_INTERACTIVE.

Returns: Promise<string> — Argon2id-encoded hash string, safe for database storage.

cryptoPwhashStrVerify(hash, password): Promise<boolean>

Verifies password against an encoded hash string.

Parameters:

  • hash: string — Encoded hash from cryptoPwhashStr.
  • password: Uint8Array — Candidate password bytes.

Returns: Promise<boolean> — true if the password matches. Returns false (not throws) on any failure including malformed hash strings.

interface PwhashOptions

  • opsLimit?: number
  • memLimit?: number

Implementation Notes

crypto_pwhash_str generates a random salt internally and encodes the full Argon2id parameter set into the output string. This is the $argon2id$v=19$... format, compatible with most password-hashing libraries. The salt is never exposed to the caller.

crypto_pwhash_str_verify uses constant-time comparison for the hash check. The try/catch maps libsodium exceptions (e.g., malformed hash strings, wrong length) to false for uniform API behaviour.

The interactive preset (OPSLIMIT_INTERACTIVE, MEMLIMIT_INTERACTIVE) is calibrated for ≈50 ms on typical hardware. Increase opsLimit and memLimit for stored API keys, encryption master passwords, or recovery codes.