or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

asymmetric-cryptography.mddigital-signatures.mdhash-functions.mdhmac.mdindex.mdkey-derivation.mdkey-exchange.mdrandom-generation.mdsymmetric-encryption.md
tile.json

hmac.mddocs/

HMAC (Hash-based Message Authentication Code)

Hash-based Message Authentication Code provides message authentication and integrity verification using a secret key and a hash function.

Capabilities

Create HMAC

Creates an HMAC object for computing keyed hash digests.

/**
 * Create an HMAC object for the specified algorithm and key
 * @param {string} algorithm - Hash algorithm name (e.g., 'sha256', 'sha1', 'md5')
 * @param {string|Buffer} key - Secret key as string or Buffer
 * @returns {Hmac} HMAC object for computing authenticated digest
 */
function createHmac(algorithm, key) { }

/**
 * HMAC object for computing keyed hash digests
 * @class Hmac
 */
/**
 * Update the HMAC with new data
 * @param {string|Buffer} data - Data to authenticate (string or Buffer)
 * @param {string} [inputEncoding='utf8'] - Encoding of input data if string
 * @returns {Hmac} HMAC object for method chaining
 */
Hmac.prototype.update = function(data, inputEncoding) { };

/**
 * Compute the final HMAC digest
 * @param {string} [encoding] - Output encoding ('hex', 'base64', 'latin1', etc.)
 * @returns {Buffer|string} HMAC digest as Buffer or encoded string
 */
Hmac.prototype.digest = function(encoding) { };

Usage Examples:

const crypto = require('crypto-browserify');

// Basic HMAC computation
const hmac = crypto.createHmac('sha256', 'secret-key')
  .update('message to authenticate')
  .digest('hex');
console.log(hmac); // "c2d0e7b5f8a9..." 

// HMAC with Buffer key
const key = crypto.randomBytes(32);
const message = 'important data';
const authenticatedHash = crypto.createHmac('sha256', key)
  .update(message)
  .digest('base64');

// Incremental HMAC computation
const incrementalHmac = crypto.createHmac('sha1', 'my-secret');
incrementalHmac.update('first part');
incrementalHmac.update('second part');
const result = incrementalHmac.digest('hex');

// HMAC for API request signing
const apiKey = 'user-api-key';
const requestBody = JSON.stringify({ action: 'transfer', amount: 100 });
const signature = crypto.createHmac('sha256', apiKey)
  .update(requestBody)
  .digest('hex');

HMAC Class Constructor

Direct access to the HMAC class for advanced usage patterns.

/**
 * HMAC class constructor (equivalent to createHmac result)
 * @constructor
 */
function Hmac() { }

Common Use Cases

Message Authentication

Verify that a message hasn't been tampered with and comes from someone who knows the secret key.

const crypto = require('crypto-browserify');

// Sender
const secretKey = 'shared-secret';
const message = 'Transfer $100 to account 12345';
const messageHmac = crypto.createHmac('sha256', secretKey)
  .update(message)
  .digest('hex');

// Send both message and HMAC to receiver
console.log('Message:', message);
console.log('HMAC:', messageHmac);

// Receiver
const receivedMessage = 'Transfer $100 to account 12345';
const receivedHmac = messageHmac;

const expectedHmac = crypto.createHmac('sha256', secretKey)
  .update(receivedMessage)
  .digest('hex');

const isAuthentic = expectedHmac === receivedHmac;
console.log('Message is authentic:', isAuthentic);

JWT Token Signing

Create HMAC signatures for JSON Web Tokens.

const crypto = require('crypto-browserify');

// JWT header and payload
const header = Buffer.from(JSON.stringify({ alg: 'HS256', typ: 'JWT' })).toString('base64');
const payload = Buffer.from(JSON.stringify({ 
  userId: 123, 
  exp: Math.floor(Date.now() / 1000) + 3600 
})).toString('base64');

const data = `${header}.${payload}`;
const secret = 'jwt-secret-key';

// Create HMAC signature
const signature = crypto.createHmac('sha256', secret)
  .update(data)
  .digest('base64')
  .replace(/\+/g, '-')
  .replace(/\//g, '_')
  .replace(/=/g, '');

const jwt = `${data}.${signature}`;
console.log('JWT:', jwt);

API Request Authentication

Authenticate API requests using HMAC signatures.

const crypto = require('crypto-browserify');

function signRequest(method, url, body, timestamp, apiSecret) {
  const stringToSign = `${method}\n${url}\n${body}\n${timestamp}`;
  
  return crypto.createHmac('sha256', apiSecret)
    .update(stringToSign)
    .digest('hex');
}

// Usage
const method = 'POST';
const url = '/api/v1/orders';
const body = JSON.stringify({ symbol: 'BTCUSD', qty: 1 });
const timestamp = Date.now();
const apiSecret = 'user-api-secret';

const signature = signRequest(method, url, body, timestamp, apiSecret);
console.log('Request signature:', signature);

Security Considerations

  • Key strength: Use cryptographically strong keys (at least 32 bytes for SHA-256)
  • Algorithm choice: Prefer SHA-256 or SHA-512 over older algorithms like SHA-1 or MD5
  • Timing attacks: Use constant-time comparison when verifying HMAC values
  • Key management: Keep secret keys secure and rotate them regularly

Error Handling

HMAC functions may throw errors in the following scenarios:

  • Unsupported algorithm: When the specified hash algorithm is not available
  • Invalid key: When the key parameter is not a string or Buffer
  • Double digest: When calling digest() multiple times on the same HMAC object
try {
  const hmac = crypto.createHmac('invalid-algo', 'key');
} catch (err) {
  console.error('Unsupported HMAC algorithm:', err.message);
}

// HMAC objects cannot be reused after digest()
const hmacObj = crypto.createHmac('sha256', 'secret');
hmacObj.update('data');
const firstDigest = hmacObj.digest('hex');

try {
  const secondDigest = hmacObj.digest('hex'); // This will throw
} catch (err) {
  console.error('Cannot reuse HMAC object:', err.message);
}