CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-sodium-native

Low level bindings for libsodium cryptographic library

Pending
Overview
Eval results
Files

pwhash.mddocs/

Password Hashing

Secure password hashing using Argon2 and scrypt algorithms for password verification, key derivation, and protection against brute-force attacks.

Capabilities

Argon2 Password Hashing

Modern password hashing using Argon2i or Argon2id algorithms.

/**
 * Hash password using Argon2
 * @param out - Output buffer for derived key
 * @param passwd - Password buffer to hash
 * @param salt - Salt buffer (must be SALTBYTES long)
 * @param opslimit - Operations limit (computational cost)
 * @param memlimit - Memory limit in bytes  
 * @param alg - Algorithm ID (ALG_ARGON2I13 or ALG_ARGON2ID13)
 * @throws Error if parameters are out of bounds or hashing fails
 */
function crypto_pwhash(
  out: Buffer, 
  passwd: Buffer, 
  salt: Buffer, 
  opslimit: number, 
  memlimit: number, 
  alg: number
): void;

Argon2 Async Password Hashing

Non-blocking password hashing for server applications.

/**
 * Hash password using Argon2 (async)
 * @param out - Output buffer for derived key
 * @param passwd - Password buffer to hash
 * @param salt - Salt buffer (must be SALTBYTES long)
 * @param opslimit - Operations limit (computational cost)
 * @param memlimit - Memory limit in bytes
 * @param alg - Algorithm ID (ALG_ARGON2I13 or ALG_ARGON2ID13)
 * @param callback - Optional callback function
 * @returns Promise<void> if no callback provided
 * @throws Error if parameters are out of bounds
 */
function crypto_pwhash_async(
  out: Buffer,
  passwd: Buffer,
  salt: Buffer,
  opslimit: number,
  memlimit: number,
  alg: number,
  callback?: (error: Error | null) => void
): Promise<void> | undefined;

Usage Example:

const sodium = require('sodium-native');

async function hashPassword(password) {
  const salt = Buffer.alloc(sodium.crypto_pwhash_SALTBYTES);
  sodium.randombytes_buf(salt);
  
  const derivedKey = Buffer.alloc(32);
  
  // Using async version (recommended for servers)
  await sodium.crypto_pwhash_async(
    derivedKey,
    Buffer.from(password),
    salt,
    sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE,
    sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE,
    sodium.crypto_pwhash_ALG_ARGON2ID13
  );
  
  return { derivedKey, salt };
}

Argon2 String Format

Password hashing with string encoding for easy storage.

/**
 * Hash password to string format
 * @param out - Output buffer for password string (must be STRBYTES long)
 * @param passwd - Password buffer to hash
 * @param opslimit - Operations limit (computational cost)
 * @param memlimit - Memory limit in bytes
 * @throws Error if parameters are out of bounds or hashing fails
 */
function crypto_pwhash_str(
  out: Buffer,
  passwd: Buffer,
  opslimit: number,
  memlimit: number
): void;

/**
 * Hash password to string format (async)
 * @param out - Output buffer for password string (must be STRBYTES long)
 * @param passwd - Password buffer to hash
 * @param opslimit - Operations limit (computational cost)
 * @param memlimit - Memory limit in bytes
 * @param callback - Optional callback function
 * @returns Promise<void> if no callback provided
 */
function crypto_pwhash_str_async(
  out: Buffer,
  passwd: Buffer,
  opslimit: number,
  memlimit: number,
  callback?: (error: Error | null) => void
): Promise<void> | undefined;

Argon2 String Verification

Verify passwords against stored string hashes.

/**
 * Verify password against string hash
 * @param str - Password string hash to verify against (must be STRBYTES long)
 * @param passwd - Password buffer to verify
 * @returns true if password matches, false otherwise
 */
function crypto_pwhash_str_verify(str: Buffer, passwd: Buffer): boolean;

/**
 * Verify password against string hash (async)
 * @param str - Password string hash to verify against (must be STRBYTES long)
 * @param passwd - Password buffer to verify
 * @param callback - Optional callback function
 * @returns Promise<boolean> if no callback provided
 */
function crypto_pwhash_str_verify_async(
  str: Buffer,
  passwd: Buffer,
  callback?: (error: Error | null, result?: boolean) => void
): Promise<boolean> | undefined;

Argon2 Rehash Check

Check if a password hash needs to be updated due to changed parameters.

/**
 * Check if password hash needs rehashing with new parameters
 * @param str - Password string hash to check (must be STRBYTES long)
 * @param opslimit - New operations limit to compare against
 * @param memlimit - New memory limit to compare against
 * @returns true if rehashing needed, false otherwise
 */
function crypto_pwhash_str_needs_rehash(
  str: Buffer,
  opslimit: number,
  memlimit: number
): boolean;

Usage Example:

const sodium = require('sodium-native');

class PasswordManager {
  async hashPassword(password) {
    const hash = Buffer.alloc(sodium.crypto_pwhash_STRBYTES);
    
    await sodium.crypto_pwhash_str_async(
      hash,
      Buffer.from(password),
      sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE,
      sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE
    );
    
    return hash;
  }
  
  async verifyPassword(password, hash) {
    return await sodium.crypto_pwhash_str_verify_async(
      hash,
      Buffer.from(password)
    );
  }
  
  needsRehash(hash) {
    return sodium.crypto_pwhash_str_needs_rehash(
      hash,
      sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE,
      sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE
    );
  }
}

Scrypt Password Hashing

Legacy scrypt algorithm support for compatibility.

/**
 * Hash password using scrypt
 * @param out - Output buffer for derived key
 * @param passwd - Password buffer to hash
 * @param salt - Salt buffer (must be SALTBYTES long)
 * @param opslimit - Operations limit (computational cost)
 * @param memlimit - Memory limit in bytes
 * @throws Error if parameters are out of bounds or hashing fails
 */
function crypto_pwhash_scryptsalsa208sha256(
  out: Buffer,
  passwd: Buffer,
  salt: Buffer,
  opslimit: number,
  memlimit: number
): void;

/**
 * Hash password using scrypt (async)
 * @param out - Output buffer for derived key
 * @param passwd - Password buffer to hash
 * @param salt - Salt buffer (must be SALTBYTES long)
 * @param opslimit - Operations limit (computational cost)
 * @param memlimit - Memory limit in bytes
 * @param callback - Optional callback function
 * @returns Promise<void> if no callback provided
 */
function crypto_pwhash_scryptsalsa208sha256_async(
  out: Buffer,
  passwd: Buffer,
  salt: Buffer,
  opslimit: number,
  memlimit: number,
  callback?: (error: Error | null) => void
): Promise<void> | undefined;

Scrypt String Format

Scrypt password hashing with string encoding.

/**
 * Hash password to string format using scrypt
 * @param out - Output buffer for password string (must be STRBYTES long)
 * @param passwd - Password buffer to hash
 * @param opslimit - Operations limit (computational cost)
 * @param memlimit - Memory limit in bytes
 * @throws Error if parameters are out of bounds or hashing fails
 */
function crypto_pwhash_scryptsalsa208sha256_str(
  out: Buffer,
  passwd: Buffer,
  opslimit: number,
  memlimit: number
): void;

/**
 * Verify password against scrypt string hash
 * @param str - Password string hash to verify against (must be STRBYTES long)
 * @param passwd - Password buffer to verify
 * @returns true if password matches, false otherwise
 */
function crypto_pwhash_scryptsalsa208sha256_str_verify(str: Buffer, passwd: Buffer): boolean;

/**
 * Check if scrypt password hash needs rehashing
 * @param str - Password string hash to check (must be STRBYTES long)
 * @param opslimit - New operations limit to compare against
 * @param memlimit - New memory limit to compare against
 * @returns true if rehashing needed, false otherwise
 */
function crypto_pwhash_scryptsalsa208sha256_str_needs_rehash(
  str: Buffer,
  opslimit: number,
  memlimit: number
): boolean;

Constants

// Argon2 algorithm constants
const crypto_pwhash_ALG_ARGON2I13: number;
const crypto_pwhash_ALG_ARGON2ID13: number;
const crypto_pwhash_ALG_DEFAULT: number;

// Argon2 size constants
const crypto_pwhash_BYTES_MIN: number;
const crypto_pwhash_BYTES_MAX: number;
const crypto_pwhash_PASSWD_MIN: number;
const crypto_pwhash_PASSWD_MAX: number;
const crypto_pwhash_SALTBYTES: number;
const crypto_pwhash_STRBYTES: number;

// Argon2 cost constants
const crypto_pwhash_OPSLIMIT_MIN: number;
const crypto_pwhash_OPSLIMIT_MAX: number;
const crypto_pwhash_OPSLIMIT_INTERACTIVE: number;
const crypto_pwhash_OPSLIMIT_MODERATE: number;
const crypto_pwhash_OPSLIMIT_SENSITIVE: number;
const crypto_pwhash_MEMLIMIT_MIN: number;
const crypto_pwhash_MEMLIMIT_MAX: number;
const crypto_pwhash_MEMLIMIT_INTERACTIVE: number;
const crypto_pwhash_MEMLIMIT_MODERATE: number;
const crypto_pwhash_MEMLIMIT_SENSITIVE: number;

// Scrypt size constants
const crypto_pwhash_scryptsalsa208sha256_BYTES_MIN: number;
const crypto_pwhash_scryptsalsa208sha256_BYTES_MAX: number;
const crypto_pwhash_scryptsalsa208sha256_PASSWD_MIN: number;
const crypto_pwhash_scryptsalsa208sha256_PASSWD_MAX: number;
const crypto_pwhash_scryptsalsa208sha256_SALTBYTES: number;
const crypto_pwhash_scryptsalsa208sha256_STRBYTES: number;

// Scrypt cost constants
const crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN: number;
const crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MAX: number;
const crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE: number;
const crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE: number;
const crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN: number;
const crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MAX: number;
const crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE: number;
const crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE: number;

Security Considerations

  • Algorithm Choice: Use Argon2id (ALG_ARGON2ID13) for new applications; it's more resistant to GPU attacks.
  • Cost Parameters: Choose appropriate opslimit/memlimit based on your security requirements and hardware.
  • Salt Uniqueness: Always use unique, random salts for each password.
  • Timing: Use async versions in server applications to prevent blocking.

Common Patterns

User Authentication System

const sodium = require('sodium-native');

class UserAuth {
  constructor() {
    this.users = new Map();
  }
  
  async registerUser(username, password) {
    const hash = Buffer.alloc(sodium.crypto_pwhash_STRBYTES);
    
    await sodium.crypto_pwhash_str_async(
      hash,
      Buffer.from(password),
      sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE,
      sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE
    );
    
    this.users.set(username, hash);
    return true;
  }
  
  async loginUser(username, password) {
    const storedHash = this.users.get(username);
    if (!storedHash) return false;
    
    // Check if hash needs updating
    if (sodium.crypto_pwhash_str_needs_rehash(
      storedHash,
      sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE,
      sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE
    )) {
      // Rehash password with new parameters after successful verification
      const isValid = await sodium.crypto_pwhash_str_verify_async(
        storedHash,
        Buffer.from(password)
      );
      
      if (isValid) {
        await this.registerUser(username, password); // Update hash
      }
      
      return isValid;
    }
    
    return await sodium.crypto_pwhash_str_verify_async(
      storedHash,
      Buffer.from(password)
    );
  }
}

Key Derivation from Password

const sodium = require('sodium-native');

async function deriveEncryptionKey(password, salt) {
  const key = Buffer.alloc(32); // 256-bit key
  
  await sodium.crypto_pwhash_async(
    key,
    Buffer.from(password),
    salt,
    sodium.crypto_pwhash_OPSLIMIT_SENSITIVE,
    sodium.crypto_pwhash_MEMLIMIT_SENSITIVE,
    sodium.crypto_pwhash_ALG_ARGON2ID13
  );
  
  return key;
}

// Usage for file encryption
async function encryptFileWithPassword(filename, password) {
  const salt = Buffer.alloc(sodium.crypto_pwhash_SALTBYTES);
  sodium.randombytes_buf(salt);
  
  const key = await deriveEncryptionKey(password, salt);
  
  // Use key with crypto_secretbox_easy
  // Store salt alongside encrypted file for decryption
}

Install with Tessl CLI

npx tessl i tessl/npm-sodium-native

docs

aead.md

auth.md

box.md

ed25519.md

hash.md

index.md

kdf.md

kx.md

memory.md

pwhash.md

random.md

secretbox.md

secretstream.md

shorthash.md

sign.md

stream.md

tile.json