JWT Signing & Encryption: Securing API Tokens
Exploring JWTs, HMAC, and RSA Signing

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
| Feature | HMAC (Symmetric) | RSA (Asymmetric) |
| Keys Used | One secret key π | Public & Private keys π |
| Security | Secure but requires secret key sharing | More secure, private key remains confidential |
| Performance | Faster | Slower (computational overhead) |
| Use Case | API 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






