Skip to main content

Command Palette

Search for a command to run...

JWT Signing & Encryption: Securing API Tokens

Exploring JWTs, HMAC, and RSA Signing

Updated
β€’3 min read
JWT Signing & Encryption: Securing API Tokens
F

Principal Technical Consultant at GeekyAnts.

Bootstrapping our own Data Centre services.

I lead the development and management of innovative software products and frameworks at GeekyAnts, leveraging a wide range of technologies including OpenStack, Postgres, MySQL, GraphQL, Docker, Redis, API Gateway, Dapr, NodeJS, NextJS, and Laravel (PHP).

With over 9 years of hands-on experience, I specialize in agile software development, CI/CD implementation, security, scaling, design, architecture, and cloud infrastructure. My expertise extends to Metal as a Service (MaaS), Unattended OS Installation, OpenStack Cloud, Data Centre Automation & Management, and proficiency in utilizing tools like OpenNebula, Firecracker, FirecrackerContainerD, Qemu, and OpenVSwitch.

I guide and mentor a team of engineers, ensuring we meet our goals while fostering strong relationships with internal and external stakeholders. I contribute to various open-source projects on GitHub and share industry and technology insights on my blog at blog.faizahmed.in.

I hold an Engineer's Degree in Computer Science and Engineering from Raj Kumar Goel Engineering College and have multiple relevant certifications showcased on my LinkedIn skill badges.

🧐 What is a JWT (JSON Web Token)?

A JWT (JSON Web Token) is a compact, self-contained token used to securely transmit information between parties. It is commonly used for authentication and authorization in APIs.

πŸ”Ή Why Use JWTs?

βœ” Stateless Authentication – No need to store session data on the server.
βœ” Compact & Efficient – JSON-based, making it lightweight.
βœ” Secure with Cryptographic Signing – Prevents token tampering.

πŸ“Œ Structure of a JWT

A JWT consists of three parts, separated by dots (.):

Header.Payload.Signature eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMjM0NTY3ODkwIiwicm9sZSI6IkFkbWluIn0.dBJzN4ELtNq3S8c9QzFQ6KGGJr3SMXsCOH1aiYZLKHk

πŸ”‘ JWT Components

1️⃣ Header

Contains metadata about the token, including:

{
  "alg": "HS256",
  "typ": "JWT"
}
  • alg: Algorithm used for signing (HMAC, RSA, etc.).

  • typ: Token type (always "JWT").

2️⃣ Payload

Contains the claims (data) to be transmitted:

{
  "userId": "1234567890",
  "role": "Admin",
  "exp": 1718312392
}
  • userId: Identifies the user.

  • role: User's access role.

  • exp: Expiration timestamp.

3️⃣ Signature

  • Prevents tampering by signing the token with a secret key (HMAC) or a private key (RSA).

  • Ensures integrity of the payload.

πŸ”Ή JWT Signing: HMAC vs RSA

FeatureHMAC (Symmetric)RSA (Asymmetric)
Keys UsedOne secret key πŸ”‘Public & Private keys πŸ”
SecuritySecure but requires secret key sharingMore secure, private key remains confidential
PerformanceFasterSlower (computational overhead)
Use CaseAPI authentication (e.g., user logins)OAuth2, secure access between services

πŸ› οΈ How to Sign & Verify JWTs in Node.js

πŸ“Œ HMAC (HS256) Signing Example

const jwt = require('jsonwebtoken');

const secretKey = "SuperSecretKey"; // Must be kept secure

// Generate JWT
const token = jwt.sign({
  userId: "1234567890",
  role: "Admin"
}, secretKey, {
  algorithm: "HS256",
  expiresIn: "1h"
});

console.log("Signed JWT:", token);

// Verify JWT
try {
  const decoded = jwt.verify(token, secretKey);
  console.log("βœ… Token is valid!", decoded);
} catch (error) {
  console.log("❌ Invalid token!");
}

πŸ“Œ RSA (RS256) Signing Example

const jwt = require('jsonwebtoken');
const fs = require('fs');

// Load Private and Public Keys
const privateKey = fs.readFileSync("private.pem", "utf8");
const publicKey = fs.readFileSync("public.pem", "utf8");

// Generate JWT
const token = jwt.sign({
  userId: "1234567890",
  role: "Admin"
}, privateKey, {
  algorithm: "RS256",
  expiresIn: "1h"
});

console.log("Signed JWT:", token);

// Verify JWT
try {
  const decoded = jwt.verify(token, publicKey);
  console.log("βœ… Token is valid!", decoded);
} catch (error) {
  console.log("❌ Invalid token!");
}

πŸ”’ When to Use JWT Signing vs Encryption?

βœ… Use JWT Signing when:
βœ” You need to verify the authenticity of tokens (e.g., user authentication).
βœ” You want a lightweight authentication mechanism.

βœ… Use JWT Encryption when:
βœ” You need to protect sensitive information inside the token.
βœ” You want end-to-end confidentiality (e.g., financial transactions).

πŸ“Œ Most APIs use signed JWTs (JWS) instead of encrypted JWTs (JWE) because the payload typically doesn’t contain confidential data.

πŸš€ Final Thoughts

JWTs are essential for securing APIs, but choosing the right signing method (HMAC vs RSA) is crucial.

  • HMAC (HS256): Fast and easy, but requires secure key sharing.

  • RSA (RS256): More secure, ideal for OAuth2 & microservices.

Would you like a tutorial on using JWTs with OAuth2 and AWS Cognito? Let’s discuss in the comments! πŸ‘‡


About Me πŸ‘¨β€πŸ’»

I'm Faiz A. Farooqui. Software Engineer from Bengaluru, India.
Find out more about me @ faizahmed.in

Mastering Encryption: A Practical Guide for Developers

Part 7 of 13

Learn encryption fundamentals, from Symmetric vs Asymmetric Encryption to Envelope Encryption and AWS KMS implementation. Clear explanations, real-world use cases, and easy-to-follow diagrams to help developers secure their data.

Up next

How Digital Signatures Ensure Data Integrity?

Verifying Authenticity in the Digital World