create-hmac provides cross-platform HMAC (Hash-based Message Authentication Code) functionality that works identically in both Node.js and browser environments. In Node.js, it delegates to the native crypto module for optimal performance, while in browsers it provides a pure JavaScript implementation with the same API.
npm install create-hmacconst createHmac = require('create-hmac');For ES modules:
import createHmac from 'create-hmac';const createHmac = require('create-hmac');
// Create HMAC instance
const hmac = createHmac('sha256', 'secret key');
// Add data (can be called multiple times)
hmac.update('Hello');
hmac.update(' World');
// Get the result
const result = hmac.digest('hex');
console.log(result); // Outputs the HMAC digest in hexadecimalCreates an HMAC instance for a specific algorithm and secret key.
/**
* Creates an HMAC instance for computing hash-based message authentication codes
* @param {string} algorithm - Hash algorithm name (case-insensitive)
* @param {string|Buffer} key - Secret key for HMAC computation
* @returns {Hmac} HMAC instance with stream interface
*/
function createHmac(algorithm, key);Supported algorithms:
'sha1' - SHA-1 hash algorithm'sha224' - SHA-224 hash algorithm'sha256' - SHA-256 hash algorithm'sha384' - SHA-384 hash algorithm'sha512' - SHA-512 hash algorithm'md5' - MD5 hash algorithm'rmd160' or 'ripemd160' - RIPEMD-160 hash algorithmUsage Examples:
// Basic HMAC creation with different algorithms
const hmacSha256 = createHmac('sha256', 'my-secret-key');
const hmacSha512 = createHmac('sha512', Buffer.from('binary-key', 'binary'));
const hmacMd5 = createHmac('md5', 'legacy-key');
// Case-insensitive algorithm names
const hmacUpper = createHmac('SHA256', 'key'); // Works the sameAdds data to the HMAC computation. Can be called multiple times to process data incrementally.
/**
* Updates the HMAC with new data
* @param {string|Buffer} data - Data to add to HMAC computation
* @param {string} [encoding] - Encoding for string data ('utf8', 'hex', 'base64', etc.)
* @returns {Hmac} Returns this for method chaining
*/
update(data, encoding);Usage Examples:
const hmac = createHmac('sha256', 'secret');
// Update with string data
hmac.update('Hello World');
// Update with specific encoding
hmac.update('48656c6c6f', 'hex'); // "Hello" in hex
// Update with Buffer
hmac.update(Buffer.from('data'));
// Method chaining
hmac.update('part1').update('part2').update('part3');Finalizes the HMAC computation and returns the result. Once called, the HMAC instance cannot be used for further updates.
/**
* Finalizes HMAC computation and returns the digest
* @param {string} [encoding] - Output encoding ('hex', 'base64', 'binary', etc.)
* @returns {Buffer|string} HMAC digest as Buffer (no encoding) or string (with encoding)
*/
digest(encoding);Usage Examples:
const hmac = createHmac('sha256', 'secret');
hmac.update('data to authenticate');
// Get digest as hex string (most common)
const hexDigest = hmac.digest('hex');
console.log(hexDigest); // "2c26b4..."
// Get digest as base64 string
const base64Digest = hmac.digest('base64');
console.log(base64Digest); // "LCa0..."
// Get digest as raw Buffer
const bufferDigest = hmac.digest();
console.log(bufferDigest); // <Buffer 2c 26 b4 ...>The HMAC instance implements Node.js stream interface, allowing it to be used in streaming contexts.
/**
* Writes data to the HMAC stream
* @param {string|Buffer} data - Data to write
* @param {string} [encoding] - Encoding for string data
* @returns {boolean} Returns true if stream can accept more data
*/
write(data, encoding);
/**
* Ends the HMAC stream, optionally writing final data
* @param {string|Buffer} [data] - Final data to write
* @param {string} [encoding] - Encoding for string data
*/
end(data, encoding);
/**
* Reads the computed HMAC digest from the stream
* @returns {Buffer} HMAC digest as Buffer
*/
read();Usage Examples:
const hmac = createHmac('sha256', 'secret');
// Stream interface usage
hmac.write('chunk1');
hmac.write('chunk2');
hmac.end(); // Signal end of data
const result = hmac.read(); // Get the digest
console.log(result.toString('hex'));
// Stream with final data
const hmac2 = createHmac('sha256', 'secret');
hmac2.write('initial data');
hmac2.end('final chunk'); // End with final data
const result2 = hmac2.read();const createHmac = require('create-hmac');
// Simple one-shot usage
function computeHmac(data, key) {
return createHmac('sha256', key)
.update(data)
.digest('hex');
}
const signature = computeHmac('important message', 'secret-key');
console.log(signature);const createHmac = require('create-hmac');
// Using as a stream
function streamHmac(dataChunks, key) {
const hmac = createHmac('sha256', key);
// Process chunks
dataChunks.forEach(chunk => {
hmac.write(chunk);
});
hmac.end(); // Signal completion
return hmac.read().toString('hex');
}
const chunks = ['Hello', ' ', 'World', '!'];
const result = streamHmac(chunks, 'my-key');
console.log(result);const createHmac = require('create-hmac');
function verifyWebhook(payload, signature, secret) {
const expectedSignature = createHmac('sha256', secret)
.update(payload)
.digest('hex');
// Compare signatures (constant-time comparison recommended in production)
return signature === `sha256=${expectedSignature}`;
}
// Usage
const isValid = verifyWebhook(
'{"event": "push"}',
'sha256=2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae',
'webhook-secret'
);crypto.createHmac for optimal performance