MAC Token

Authentication Security Notes Jan 6, 2025 JAVASCRIPT

Definition

Imagine you have a house key that anyone could copy and use. That’s essentially how bearer tokens work - if someone steals your token, they can pretend to be you. MAC tokens solve this problem by adding a layer of proof that you’re the rightful owner of that token.

With MAC tokens, you don’t just show your token to access an API - you have to prove you actually possess a secret key that goes with it. Every time you make a request, you create a unique cryptographic signature (called a Message Authentication Code) that’s calculated using your secret key, the details of your request, and a timestamp. The server checks this signature to verify two things: that you have the real token AND that you know the secret key associated with it.

Here’s why this matters: if a hacker intercepts your request and sees your MAC token, they can’t simply replay it or use it for different requests. The signature only works for that specific request at that specific time. It’s like the difference between someone photographing your signature (bearer token) versus having to sign a new document in person each time (MAC token). The MAC token approach makes token theft much less useful to attackers because they can’t use a stolen token for different operations.

Example

MAC tokens shine in high-security scenarios where bearer tokens simply aren’t safe enough. Here are situations where they’re particularly valuable:

Financial API Integrations: When a fintech app connects to a bank’s API to initiate money transfers, bearer tokens would be risky. If someone intercepted a bearer token, they could potentially drain accounts. With MAC tokens, every transfer request requires a fresh cryptographic proof that the legitimate app is making the request. Even if an attacker captures a transfer request in transit, they can’t modify the amount or destination because changing anything invalidates the signature.

Trading Platforms: High-frequency trading systems that execute orders worth millions need bulletproof authentication. A MAC token ensures that a “buy 10,000 shares of Apple” order can’t be tampered with to become “buy 10,000 shares of something else” or replayed multiple times. Each order carries its own unique mathematical proof of authenticity.

Healthcare Data Exchanges: When hospitals share patient records through APIs, the consequences of a breach are severe. MAC tokens ensure that a request for “patient John Doe’s blood test results” can’t be intercepted and altered to request someone else’s records. The signature mathematically locks the request to its original parameters.

IoT Device Commands: Consider a smart grid where commands are sent to power stations. You wouldn’t want an attacker to intercept a “reduce power by 5%” command and replay it a hundred times. MAC tokens ensure each command is uniquely signed and can only be executed once.

Analogy

The Notarized Signature: Think about the difference between signing a check and getting a document notarized. Anyone can forge a signature if they’ve seen it before (like stealing a bearer token). But notarization requires you to show up in person, prove your identity, and have the notary witness you signing right then and there. A MAC token is like getting every single request notarized - you have to prove, in real-time, that you’re actually the person with authority to make that request.

The Challenge-Response Lock: Imagine a high-security lock that doesn’t just accept any key. Each time you try to open it, the lock displays a random number, and you must use your special calculator (your secret key) to compute the correct response. Even if someone watches you open the door once, they can’t get in later because the challenge changes every time. That’s how MAC tokens work - the signature incorporates changing elements (timestamp, nonce) so no two signatures are alike.

The Chef’s Secret Recipe: Picture a restaurant where the chef creates a unique seasoning blend for each dish, incorporating the customer’s table number, the time of order, and a secret spice only the chef knows. Any imposter trying to serve a dish would fail because they don’t know the secret spice and couldn’t recreate the exact blend. MAC tokens work similarly - without the secret key, you can’t create valid signatures.

The Military Challenge Coin: In military tradition, members of certain units carry challenge coins. When challenged, you must produce your coin. But unlike just showing an ID card, the coin ritual often involves specific presentations and countersigns that prove you’re not just holding a stolen coin. MAC tokens require you to demonstrate ongoing knowledge (the ability to generate valid signatures), not just possession of a static credential.

Code Example


// MAC Token authentication (concept)
const crypto = require('crypto');

function createMacSignature(macKey, timestamp, nonce, method, uri, host) {
  const normalizedString =
    `${timestamp}\n${nonce}\n${method}\n${uri}\n${host}\n`;

  return crypto
    .createHmac('sha256', macKey)
    .update(normalizedString)
    .digest('base64');
}

// Client request with MAC token
const timestamp = Math.floor(Date.now() / 1000);
const nonce = crypto.randomBytes(16).toString('hex');
const mac = createMacSignature(
  macKey,
  timestamp,
  nonce,
  'GET',
  '/api/resource',
  'api.example.com'
);

fetch('https://api.example.com/api/resource', {
  headers: {
    'Authorization': `MAC id="${tokenId}", ts="${timestamp}", nonce="${nonce}", mac="${mac}"`
  }
});

// Server verification
function verifyMac(req, macKey) {
  const { id, ts, nonce, mac } = parseMacHeader(req.headers.authorization);
  const expectedMac = createMacSignature(macKey, ts, nonce, req.method, req.path, req.hostname);

  // Check timestamp freshness (prevent replay)
  const age = Date.now() / 1000 - ts;
  if (age > 300) return false; // Reject if older than 5 minutes

  return crypto.timingSafeEqual(Buffer.from(mac), Buffer.from(expectedMac));
}

Diagram

sequenceDiagram
    participant Client
    participant API

    Note over Client: Has token ID + MAC secret key

    rect rgb(230, 255, 230)
        Note over Client: MAC Token: Request is SIGNED
        Client->>Client: 1. Construct request data:
timestamp + nonce + method + uri + host Client->>Client: 2. Calculate MAC signature:
HMAC-SHA256(data, secret_key) Client->>API: 3. Request + MAC header
Authorization: MAC id="...", ts="...", nonce="...", mac="..." end API->>API: 4. Reconstruct expected MAC API->>API: 5. Compare signatures (timing-safe) API->>API: 6. Check timestamp freshness API->>Client: 7. Response rect rgb(255, 230, 230) Note over Client,API: Compare to Bearer Token Client->>API: Bearer: Just sends token
Attacker can reuse stolen token end rect rgb(230, 255, 230) Note over Client,API: MAC Token Advantage Note over API: Each request has unique signature.
Stolen request cannot be replayed
or modified. end

Security Notes

SECURITY NOTES

CRITICAL: MAC (Message Authentication Code) tokens use shared secret. Similar to HMAC.

MAC Token Concept:

  • Shared secret: Client and server share secret key
  • Signature: Request signed with shared secret
  • Verification: Server verifies signature matches

Usage Pattern:

  • Token format: [algorithm, credential, signature]
  • Signature calculation: Sign method, URI, body, timestamp
  • Expiration: Include timestamp to prevent replay
  • Nonce: Optional nonce for additional security

Security Considerations:

  • Shared secrets: Must be strong and random
  • Key management: Secure key distribution and rotation
  • Replay prevention: Timestamp validation critical
  • HTTPS requirement: Still require HTTPS
  • Timing attacks: Use constant-time comparison

Vulnerabilities:

  • Shared secret exposure: Compromises all tokens
  • No perfect forward secrecy: Old tokens remain valid
  • Replay attacks: Timestamps must be validated
  • Algorithm confusion: Validate algorithm matches

Standards & RFCs

Standards & RFCs