Get a Pentest and security assessment of your IT network.

Cyber Security

JWT Authentication: Signature Only

TL;DR

This guide shows how to create a basic JWT authentication system using only the signature part of a standard JWT, for scenarios where minimal data transfer is required. This approach significantly reduces token size but requires careful handling of shared secrets.

Prerequisites

  • A server-side environment (e.g., Node.js, Python, PHP).
  • A library capable of generating and verifying HMAC signatures (e.g., crypto in Node.js, hmac in Python).

Steps

  1. Choose a Secret Key: This is crucial. The security of your system depends on keeping this key secret and strong. Use a long, random string.
    const secretKey = 'your-very-secret-key';
  2. Generate the Signature: Instead of creating a full JWT with header and payload, we’ll only generate the signature based on some identifier (e.g., user ID).

    The process involves hashing the identifier using your secret key.

    const crypto = require('crypto');
    
    function generateSignature(identifier) {
      const hash = crypto.createHmac('sha256', secretKey).update(identifier).digest('hex');
      return hash;
    }
    
    // Example:
    const userId = '12345';
    const signature = generateSignature(userId);
    console.log(signature);
  3. Send the Signature to the Client: Transmit this signature (e.g., in a cookie or as part of an API response). Avoid sending any sensitive user data.

    For example, you might set it as an HTTP-only cookie.

  4. Verify the Signature on Subsequent Requests: On each request, recalculate the signature based on the identifier and compare it to the received signature.
    function verifySignature(identifier, receivedSignature) {
      const calculatedSignature = generateSignature(identifier);
      return crypto.timingSafeEqual(Buffer.from(calculatedSignature), Buffer.from(receivedSignature));
    }
    
    // Example:
    const userIdFromRequest = '12345'; // Get this from the request (e.g., user ID in session)
    const receivedSignatureFromCookie = req.cookies.signature;
    
    if (verifySignature(userIdFromRequest, receivedSignatureFromCookie)) {
      // Signature is valid - allow access.
      console.log('Signature verified!');
    } else {
      // Signature is invalid - reject request.
      console.log('Invalid signature!');
    }
    
  5. Important Security Considerations:
    • Shared Secret Management: Protect the secret key at all costs. Do not hardcode it directly into your application code. Use environment variables or a secure configuration management system.
    • Identifier Uniqueness: Ensure that the identifier used to generate the signature is unique for each user and cannot be easily guessed or manipulated.
    • HTTPS Only: Always transmit signatures over HTTPS to prevent interception.
    • Limited Scope: This method provides minimal security compared to full JWT authentication. It’s suitable only for scenarios where you trust the client environment and require very small token sizes.
    • No Payload: Because there is no payload, you cannot store any user information in the token itself. All user data must be retrieved from a server-side database or session storage.
Related posts
Cyber Security

Zip Codes & PII: Are They Personal Data?

Cyber Security

Zero-Day Vulnerabilities: User Defence Guide

Cyber Security

Zero Knowledge Voting with Trusted Server

Cyber Security

ZeroNet: 51% Attack Risks & Mitigation