CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-crypto-js

JavaScript library of crypto standards providing comprehensive cryptographic algorithms including hashing, encryption, HMAC, and encoding utilities.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

key-derivation.mddocs/

Key Derivation Functions

Password-based key derivation functions for generating cryptographic keys from passwords or passphrases. These functions apply computational cost to make brute-force attacks more difficult and derive keys suitable for cryptographic operations.

Capabilities

PBKDF2 (Password-Based Key Derivation Function 2)

PBKDF2 with configurable iteration count and hash function. Recommended for modern applications with high iteration counts.

/**
 * Derives a key from password using PBKDF2
 * @param password - String or WordArray password/passphrase
 * @param salt - String or WordArray salt value
 * @param cfg - Configuration object with keySize, iterations, and hasher
 * @returns WordArray containing the derived key
 */
CryptoJS.PBKDF2(password, salt, cfg)

Usage Examples:

var CryptoJS = require("crypto-js");

// Basic PBKDF2 key derivation
var password = "user-password";
var salt = CryptoJS.lib.WordArray.random(128/8); // Random 128-bit salt

var key = CryptoJS.PBKDF2(password, salt, {
    keySize: 256/32,      // 256-bit key (8 words)
    iterations: 250000    // High iteration count for security
});

console.log("Derived key:", key.toString());
console.log("Salt:", salt.toString());

// PBKDF2 with custom hash function
var keyWithSHA512 = CryptoJS.PBKDF2(password, salt, {
    keySize: 512/32,              // 512-bit key
    iterations: 100000,
    hasher: CryptoJS.algo.SHA512  // Use SHA-512 instead of default SHA-256
});

// PBKDF2 for AES key generation
var aesKey = CryptoJS.PBKDF2("strong-password", salt, {
    keySize: 256/32,    // AES-256 key size
    iterations: 250000
});

var message = "Secret data";
var encrypted = CryptoJS.AES.encrypt(message, aesKey);
console.log("Encrypted with PBKDF2 key:", encrypted.toString());

EvpKDF (OpenSSL EVP Key Derivation Function)

OpenSSL-compatible key derivation function for compatibility with OpenSSL encrypted data.

/**
 * Derives a key from password using OpenSSL EVP KDF
 * @param password - String or WordArray password/passphrase
 * @param salt - String or WordArray salt value
 * @param cfg - Configuration object with keySize and iterations
 * @returns WordArray containing the derived key
 */
CryptoJS.EvpKDF(password, salt, cfg)

Usage Examples:

var CryptoJS = require("crypto-js");

// Basic EvpKDF key derivation
var password = "password123";
var salt = CryptoJS.enc.Hex.parse("0123456789abcdef"); // 8-byte salt

var key = CryptoJS.EvpKDF(password, salt, {
    keySize: 128/32,  // 128-bit key (4 words)
    iterations: 1     // Default iteration count (legacy compatibility)
});

console.log("EvpKDF derived key:", key.toString());

// EvpKDF for OpenSSL compatibility
var opensslKey = CryptoJS.EvpKDF(password, salt, {
    keySize: 256/32 + 128/32,  // Key + IV size for AES-256
    iterations: 1
});

// Split key and IV
var keyPart = CryptoJS.lib.WordArray.create(opensslKey.words.slice(0, 8)); // First 8 words (256 bits)
var ivPart = CryptoJS.lib.WordArray.create(opensslKey.words.slice(8, 12)); // Next 4 words (128 bits)

var message = "OpenSSL compatible data";
var encrypted = CryptoJS.AES.encrypt(message, keyPart, { iv: ivPart });

Advanced Key Derivation Patterns

Secure Key Storage Pattern

var CryptoJS = require("crypto-js");

function deriveKeyWithSalt(password, storedSalt) {
    // If no salt provided, generate a new one
    var salt = storedSalt || CryptoJS.lib.WordArray.random(128/8);
    
    var key = CryptoJS.PBKDF2(password, salt, {
        keySize: 256/32,
        iterations: 250000
    });
    
    return {
        key: key,
        salt: salt
    };
}

// First time - generate salt
var result = deriveKeyWithSalt("user-password");
console.log("Salt to store:", result.salt.toString());

// Later - use stored salt
var storedSalt = CryptoJS.enc.Hex.parse(result.salt.toString());
var derivedAgain = deriveKeyWithSalt("user-password", storedSalt);
console.log("Keys match:", result.key.toString() === derivedAgain.key.toString());

Multi-Purpose Key Derivation

var CryptoJS = require("crypto-js");

function deriveMultipleKeys(masterPassword, salt, purposes) {
    var keys = {};
    
    purposes.forEach(function(purpose, index) {
        // Create unique salt for each purpose
        var purposeSalt = CryptoJS.lib.WordArray.create(salt.words.concat([index]));
        
        keys[purpose] = CryptoJS.PBKDF2(masterPassword, purposeSalt, {
            keySize: 256/32,
            iterations: 150000
        });
    });
    
    return keys;
}

// Usage
var masterPassword = "master-secret";
var salt = CryptoJS.lib.WordArray.random(128/8);

var keys = deriveMultipleKeys(masterPassword, salt, [
    'encryption',
    'authentication', 
    'signing'
]);

console.log("Encryption key:", keys.encryption.toString());
console.log("Authentication key:", keys.authentication.toString());
console.log("Signing key:", keys.signing.toString());

Password Stretching for Storage

var CryptoJS = require("crypto-js");

function hashPasswordForStorage(password, salt, iterations) {
    salt = salt || CryptoJS.lib.WordArray.random(128/8);
    iterations = iterations || 250000;
    
    var hash = CryptoJS.PBKDF2(password, salt, {
        keySize: 256/32,
        iterations: iterations
    });
    
    return {
        hash: hash.toString(),
        salt: salt.toString(),
        iterations: iterations
    };
}

function verifyPassword(password, stored) {
    var salt = CryptoJS.enc.Hex.parse(stored.salt);
    var hash = CryptoJS.PBKDF2(password, salt, {
        keySize: 256/32,
        iterations: stored.iterations
    });
    
    return hash.toString() === stored.hash;
}

// Usage
var stored = hashPasswordForStorage("user-password");
console.log("Stored hash:", stored.hash);

var isValid = verifyPassword("user-password", stored);
console.log("Password valid:", isValid);

Key Derivation Timing Analysis

var CryptoJS = require("crypto-js");

function benchmarkKDF(password, salt, iterations) {
    var start = Date.now();
    
    var key = CryptoJS.PBKDF2(password, salt, {
        keySize: 256/32,
        iterations: iterations
    });
    
    var duration = Date.now() - start;
    
    return {
        key: key,
        duration: duration,
        iterationsPerSecond: Math.round(iterations / (duration / 1000))
    };
}

// Find optimal iteration count for ~100ms derivation time
var testSalt = CryptoJS.lib.WordArray.random(128/8);
var testIterations = [10000, 50000, 100000, 250000, 500000];

testIterations.forEach(function(iterations) {
    var result = benchmarkKDF("test-password", testSalt, iterations);
    console.log(`${iterations} iterations: ${result.duration}ms (${result.iterationsPerSecond} iter/sec)`);
});

Types

// PBKDF2 Configuration
PBKDF2Config {
  keySize?: number;       // Key size in words (default: 4, i.e., 128 bits)
  iterations?: number;    // Iteration count (default: 250000)
  hasher?: Object;        // Hash function (default: SHA256)
}

// EvpKDF Configuration  
EvpKDFConfig {
  keySize?: number;       // Key size in words (default: 4, i.e., 128 bits)
  iterations?: number;    // Iteration count (default: 1)
}

// Key Derivation Result
WordArray {
  words: number[];        // Array of 32-bit words containing the key
  sigBytes: number;       // Number of significant bytes
  toString(encoder?): string; // Convert to string representation
  clone(): WordArray;     // Create a copy of the key
}

Install with Tessl CLI

npx tessl i tessl/npm-crypto-js

docs

cipher-config.md

encoding.md

encryption.md

hash-functions.md

hmac.md

index.md

key-derivation.md

tile.json