CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-mz

Promise-based wrappers for Node.js core APIs that modernize callback-based methods to work with async/await patterns

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

crypto.mddocs/

Cryptographic Operations

Generate random data and perform key derivation with promise support. Provides modern async/await compatibility for Node.js crypto operations.

Capabilities

Random Data Generation

Generate cryptographically secure random data.

/**
 * Generate cryptographically strong random data
 * @param size - Number of bytes to generate
 * @returns Promise resolving to Buffer containing random bytes
 */
function randomBytes(size): Promise<Buffer>;

/**
 * Generate pseudo-random data (less secure than randomBytes)
 * @param size - Number of bytes to generate  
 * @returns Promise resolving to Buffer containing pseudo-random bytes
 */
function pseudoRandomBytes(size): Promise<Buffer>;

Key Derivation

Derive cryptographic keys using PBKDF2 algorithm.

/**
 * PBKDF2 key derivation function
 * @param password - Password string or Buffer
 * @param salt - Salt string or Buffer
 * @param iterations - Number of iterations
 * @param keylen - Desired key length in bytes
 * @param digest - Digest algorithm (e.g., 'sha256', 'sha512')
 * @returns Promise resolving to derived key Buffer
 */
function pbkdf2(password, salt, iterations, keylen, digest): Promise<Buffer>;

Usage Examples:

const crypto = require('mz/crypto');

// Generate random data
async function generateRandomData() {
  try {
    // Generate 16 random bytes
    const randomData = await crypto.randomBytes(16);
    console.log('Random hex:', randomData.toString('hex'));
    console.log('Random base64:', randomData.toString('base64'));
    
    // Generate larger amounts
    const largeRandom = await crypto.randomBytes(256);
    console.log('Large random data length:', largeRandom.length);
    
  } catch (error) {
    console.error('Random generation failed:', error);
  }
}

// Generate pseudo-random data (faster but less secure)
async function generatePseudoRandom() {
  try {
    const pseudoData = await crypto.pseudoRandomBytes(32);
    console.log('Pseudo-random hex:', pseudoData.toString('hex'));
  } catch (error) {
    console.error('Pseudo-random generation failed:', error);
  }
}

// Key derivation
async function deriveKey() {
  try {
    const password = 'user-password';
    const salt = await crypto.randomBytes(16); // Generate random salt
    
    // Derive key using PBKDF2
    const derivedKey = await crypto.pbkdf2(
      password,     // Password
      salt,         // Salt
      100000,       // Iterations (higher = more secure but slower)
      32,           // Key length in bytes
      'sha256'      // Hash algorithm
    );
    
    console.log('Derived key:', derivedKey.toString('hex'));
    console.log('Salt used:', salt.toString('hex'));
    
  } catch (error) {
    console.error('Key derivation failed:', error);
  }
}

// Callback support is still available
crypto.randomBytes(8, (err, buffer) => {
  if (err) {
    console.error('Error:', err);
  } else {
    console.log('Random bytes:', buffer.toString('hex'));
  }
});

// Practical example: Generate API key
async function generateApiKey() {
  try {
    const key = await crypto.randomBytes(32);
    const apiKey = key.toString('base64url'); // URL-safe base64
    console.log('Generated API key:', apiKey);
    return apiKey;
  } catch (error) {
    throw new Error('Failed to generate API key: ' + error.message);
  }
}

// Practical example: Password hashing preparation
async function preparePasswordHash(password) {
  try {
    // Generate salt
    const salt = await crypto.randomBytes(16);
    
    // Derive key (this would be stored as the password hash)
    const hash = await crypto.pbkdf2(password, salt, 100000, 64, 'sha512');
    
    return {
      salt: salt.toString('hex'),
      hash: hash.toString('hex')
    };
  } catch (error) {
    throw new Error('Password hashing failed: ' + error.message);
  }
}

Error Handling

All crypto functions will reject with an error when:

  • Invalid parameters are provided
  • System entropy is insufficient (rare)
  • The requested size is too large
  • Invalid digest algorithm is specified (for pbkdf2)
const crypto = require('mz/crypto');

async function handleCryptoErrors() {
  try {
    // This will fail if size is negative or too large
    await crypto.randomBytes(-1);
  } catch (error) {
    console.error('Invalid size:', error.message);
  }
  
  try {
    // This will fail with invalid digest
    await crypto.pbkdf2('password', 'salt', 1000, 32, 'invalid-digest');
  } catch (error) {
    console.error('Invalid digest:', error.message);
  }
}

Security Considerations

  • Use randomBytes() for cryptographic purposes: It provides cryptographically secure random data
  • Avoid pseudoRandomBytes() for security-critical applications: It's faster but less secure
  • Use sufficient PBKDF2 iterations: At least 100,000 iterations recommended for password hashing
  • Always use random salts: Generate a new salt for each password/key derivation
  • Choose appropriate key lengths: 32 bytes (256 bits) minimum for symmetric keys

Implementation Notes

  • Uses thenify-all to wrap native crypto methods
  • Maintains complete compatibility with native crypto behavior
  • Supports both promise and callback interfaces
  • All functions return Buffers (use .toString() methods for string conversion)
  • Error behavior matches native crypto module exactly

docs

child-process.md

crypto.md

dns.md

fs.md

index.md

readline.md

zlib.md

tile.json