Low level bindings for libsodium cryptographic library
—
Secure password hashing using Argon2 and scrypt algorithms for password verification, key derivation, and protection against brute-force attacks.
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;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 };
}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;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;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
);
}
}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 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;// 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;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)
);
}
}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