CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-jssha

Pure TypeScript/JavaScript streaming implementation of the complete Secure Hash Standard (SHA) family with HMAC support

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

hmac-operations.mddocs/

HMAC Operations

Hash-based Message Authentication Code (HMAC) functionality for creating and verifying message authenticity and integrity. jsSHA provides built-in HMAC support for all applicable SHA variants with flexible key input formats.

Capabilities

HMAC via Constructor Options (Recommended)

The preferred method for HMAC operations is to specify the HMAC key during object instantiation.

/**
 * HMAC options for TEXT input format with encoding support
 */
interface FixedLengthOptionsEncodingType {
  hmacKey?: GenericInputType;
  encoding?: EncodingType;
} | {
  numRounds?: number;
  encoding?: EncodingType;
}

/**
 * HMAC options for non-TEXT input formats
 */
interface FixedLengthOptionsNoEncodingType {
  hmacKey?: GenericInputType;
} | {
  numRounds?: number;
}

/**
 * Generic input specification for HMAC keys
 */
interface GenericInputType {
  value: string;
  format: "TEXT";
  encoding?: EncodingType;
} | {
  value: string;
  format: "B64" | "HEX" | "BYTES";
} | {
  value: ArrayBuffer;
  format: "ARRAYBUFFER";
} | {
  value: Uint8Array;
  format: "UINT8ARRAY";
}

type EncodingType = "UTF8" | "UTF16BE" | "UTF16LE";

Usage Examples:

import jsSHA from "jssha";

// HMAC with text key
const hmacText = new jsSHA("SHA-256", "TEXT", {
  hmacKey: { value: "secret-key", format: "TEXT" },
  encoding: "UTF8"
});
hmacText.update("Message to authenticate");
const hmac1 = hmacText.getHash("HEX");

// HMAC with hex key
const hmacHex = new jsSHA("SHA-512", "TEXT", {
  hmacKey: { value: "deadbeef", format: "HEX" }
});
hmacHex.update("Another message");
const hmac2 = hmacHex.getHash("B64");

// HMAC with Base64 key
const hmacB64 = new jsSHA("SHA-1", "HEX", {
  hmacKey: { value: "c2VjcmV0LWtleQ==", format: "B64" }
});
hmacB64.update("48656c6c6f"); // "Hello" in hex
const hmac3 = hmacB64.getHash("HEX");

// HMAC with ArrayBuffer key
const keyBuffer = new TextEncoder().encode("binary-key").buffer;
const hmacBuffer = new jsSHA("SHA-384", "ARRAYBUFFER", {
  hmacKey: { value: keyBuffer, format: "ARRAYBUFFER" }
});
const messageBuffer = new TextEncoder().encode("Message").buffer;
hmacBuffer.update(messageBuffer);
const hmac4 = hmacBuffer.getHash("UINT8ARRAY");

// HMAC with Uint8Array key
const keyArray = new TextEncoder().encode("array-key");
const hmacArray = new jsSHA("SHA3-256", "UINT8ARRAY", {
  hmacKey: { value: keyArray, format: "UINT8ARRAY" }
});
const messageArray = new TextEncoder().encode("Message");
hmacArray.update(messageArray);
const hmac5 = hmacArray.getHash("ARRAYBUFFER");

Legacy setHMACKey Method (Deprecated)

The setHMACKey method is deprecated in favor of specifying the HMAC key in constructor options, but remains available for backward compatibility.

/**
 * Sets the HMAC key for TEXT format keys (DEPRECATED)
 * @param key - The HMAC key as a string
 * @param inputFormat - Must be "TEXT"
 * @param options - Optional encoding configuration
 */
setHMACKey(key: string, inputFormat: "TEXT", options?: { encoding?: EncodingType }): void;

/**
 * Sets the HMAC key for string-based formats (DEPRECATED)
 * @param key - The HMAC key as a string
 * @param inputFormat - Key format: B64, HEX, or BYTES
 */
setHMACKey(key: string, inputFormat: "B64" | "HEX" | "BYTES"): void;

/**
 * Sets the HMAC key for ArrayBuffer format (DEPRECATED)
 * @param key - The HMAC key as ArrayBuffer
 * @param inputFormat - Must be "ARRAYBUFFER"
 */
setHMACKey(key: ArrayBuffer, inputFormat: "ARRAYBUFFER"): void;

/**
 * Sets the HMAC key for Uint8Array format (DEPRECATED)
 * @param key - The HMAC key as Uint8Array
 * @param inputFormat - Must be "UINT8ARRAY"
 */
setHMACKey(key: Uint8Array, inputFormat: "UINT8ARRAY"): void;

Usage Example (Deprecated Pattern):

import jsSHA from "jssha";

// Deprecated approach - avoid in new code
const shaObj = new jsSHA("SHA-256", "TEXT");
shaObj.setHMACKey("secret-key", "TEXT", { encoding: "UTF8" });
shaObj.update("Message to authenticate");
const hmac = shaObj.getHash("HEX"); // Use getHash, not getHMAC

Legacy getHMAC Method (Deprecated)

The getHMAC method is deprecated in favor of using getHash after setting up HMAC in the constructor.

/**
 * Returns the HMAC in hexadecimal format (DEPRECATED)
 * @param format - Must be "HEX"
 * @param options - Optional formatting options
 * @returns HMAC as hexadecimal string
 */
getHMAC(format: "HEX", options?: { outputUpper?: boolean }): string;

/**
 * Returns the HMAC in Base64 format (DEPRECATED)
 * @param format - Must be "B64"
 * @param options - Optional formatting options
 * @returns HMAC as Base64 string
 */
getHMAC(format: "B64", options?: { b64Pad?: string }): string;

/**
 * Returns the HMAC as a byte string (DEPRECATED)
 * @param format - Must be "BYTES"
 * @returns HMAC as byte string
 */
getHMAC(format: "BYTES"): string;

/**
 * Returns the HMAC as a Uint8Array (DEPRECATED)
 * @param format - Must be "UINT8ARRAY"
 * @returns HMAC as Uint8Array
 */
getHMAC(format: "UINT8ARRAY"): Uint8Array;

/**
 * Returns the HMAC as an ArrayBuffer (DEPRECATED)
 * @param format - Must be "ARRAYBUFFER"
 * @returns HMAC as ArrayBuffer
 */
getHMAC(format: "ARRAYBUFFER"): ArrayBuffer;

HMAC-Compatible Variants

HMAC is supported for the following SHA variants:

  • SHA-1: HMAC-SHA1 (legacy, not recommended for new applications)
  • SHA-224: HMAC-SHA224
  • SHA-256: HMAC-SHA256 (most commonly used)
  • SHA-384: HMAC-SHA384
  • SHA-512: HMAC-SHA512
  • SHA3-224: HMAC-SHA3-224
  • SHA3-256: HMAC-SHA3-256
  • SHA3-384: HMAC-SHA3-384
  • SHA3-512: HMAC-SHA3-512

Note: HMAC is not applicable to variable-length variants (SHAKE, cSHAKE) or KMAC variants (which have their own keyed authentication mechanism).

Key Format Considerations

Text Keys

When using TEXT format keys, the encoding parameter determines how the string is converted to bytes:

// UTF-8 encoding (default and recommended)
const hmac1 = new jsSHA("SHA-256", "TEXT", {
  hmacKey: { value: "secret-key", format: "TEXT", encoding: "UTF8" }
});

// UTF-16 Big Endian encoding
const hmac2 = new jsSHA("SHA-256", "TEXT", {
  hmacKey: { value: "secret-key", format: "TEXT", encoding: "UTF16BE" }
});

// UTF-16 Little Endian encoding
const hmac3 = new jsSHA("SHA-256", "TEXT", {
  hmacKey: { value: "secret-key", format: "TEXT", encoding: "UTF16LE" }
});

Binary Keys

For keys that are already in binary format or need specific byte representations:

// Hexadecimal key (useful for keys generated as hex strings)
const hmacHex = new jsSHA("SHA-256", "TEXT", {
  hmacKey: { value: "deadbeefcafebabe", format: "HEX" }
});

// Base64 key (useful for keys stored in Base64 format)
const hmacB64 = new jsSHA("SHA-256", "TEXT", {
  hmacKey: { value: "c2VjcmV0LWtleQ==", format: "B64" }
});

// Raw bytes key (for precise byte control)
const hmacBytes = new jsSHA("SHA-256", "TEXT", {
  hmacKey: { value: "\x00\x01\x02\x03", format: "BYTES" }
});

Binary Object Keys

For keys provided as JavaScript binary objects:

// ArrayBuffer key
const keyBuffer = new Uint8Array([0x00, 0x01, 0x02, 0x03]).buffer;
const hmacBuffer = new jsSHA("SHA-256", "TEXT", {
  hmacKey: { value: keyBuffer, format: "ARRAYBUFFER" }
});

// Uint8Array key
const keyArray = new Uint8Array([0x00, 0x01, 0x02, 0x03]);
const hmacArray = new jsSHA("SHA-256", "TEXT", {
  hmacKey: { value: keyArray, format: "UINT8ARRAY" }
});

Common HMAC Patterns

API Request Authentication

import jsSHA from "jssha";

function signRequest(method: string, url: string, body: string, secretKey: string): string {
  const message = `${method}\n${url}\n${body}`;
  const hmac = new jsSHA("SHA-256", "TEXT", {
    hmacKey: { value: secretKey, format: "TEXT" }
  });
  hmac.update(message);
  return hmac.getHash("B64");
}

const signature = signRequest("POST", "/api/users", '{"name":"John"}', "my-secret-key");
// Use signature in Authorization header

Message Integrity Verification

import jsSHA from "jssha";

function verifyMessage(message: string, expectedHmac: string, secretKey: string): boolean {
  const hmac = new jsSHA("SHA-256", "TEXT", {
    hmacKey: { value: secretKey, format: "TEXT" }
  });
  hmac.update(message);
  const computedHmac = hmac.getHash("HEX");
  
  // Constant-time comparison to prevent timing attacks
  return computedHmac === expectedHmac;
}

const isValid = verifyMessage("Hello, World!", "expected-hmac-hex", "shared-secret");

JWT-style Token Signing

import jsSHA from "jssha";

function createToken(header: string, payload: string, secret: string): string {
  const message = `${header}.${payload}`;
  const hmac = new jsSHA("SHA-256", "TEXT", {
    hmacKey: { value: secret, format: "TEXT" }
  });
  hmac.update(message);
  const signature = hmac.getHash("B64");
  return `${message}.${signature}`;
}

const token = createToken("eyJhbGciOiJIUzI1NiJ9", "eyJ1c2VyIjoiam9obiJ9", "jwt-secret");

Security Considerations

  1. Key Length: HMAC keys should be at least as long as the hash output length for optimal security
  2. Key Storage: Store HMAC keys securely and never log or expose them
  3. Timing Attacks: Use constant-time comparison when verifying HMAC values
  4. Algorithm Choice: Prefer SHA-256 or stronger variants for new applications
  5. Key Rotation: Implement regular key rotation for long-lived applications

Error Handling

HMAC operations can fail if:

  • Invalid key formats are provided
  • The specified SHA variant doesn't support HMAC
  • numRounds parameter is used with HMAC (not supported)
// This will work correctly
const validHmac = new jsSHA("SHA-256", "TEXT", {
  hmacKey: { value: "secret", format: "TEXT" }
});

// This will NOT work - numRounds cannot be used with HMAC
try {
  const invalidHmac = new jsSHA("SHA-256", "TEXT", {
    hmacKey: { value: "secret", format: "TEXT" },
    numRounds: 5 // Error: numRounds not valid with HMAC
  });
} catch (error) {
  console.error("Invalid HMAC configuration");
}

docs

advanced-sha3.md

core-hashing.md

hmac-operations.md

index.md

variant-classes.md

tile.json