Generate JWT Secrets Instantly
Create cryptographically secure JWT signing secrets for your applications. Generate strong keys for JSON Web Token authentication and authorization.
JWT Secret Options
JWT Best Practices
Excludes characters that need URL encoding
Ensures maximum randomness for JWT signing
Output as base64 encoded string
Bulk Generation
JWT Security Best Practices
Learn how to properly secure your JWT implementations with strong signing secrets
Strong Secret Keys
Use cryptographically secure secrets with at least 256 bits of entropy. Never use predictable or short secrets.
Environment Variables
Store JWT secrets in environment variables, never hardcode them in your source code or configuration files.
Regular Rotation
Implement secret rotation policies. Change JWT secrets periodically and when security incidents occur.
Algorithm Selection
Use HS256 minimum, prefer HS384 or HS512 for higher security. Avoid 'none' algorithm and weak signing methods.
Short Expiration
Set appropriate expiration times. Use short-lived tokens with refresh token patterns for better security.
Secure Transmission
Always transmit JWTs over HTTPS. Use secure headers and implement proper CORS policies.
JWT Algorithm Comparison
Choose the right HMAC algorithm for your security requirements
Algorithm | Secret Length | Hash Output | Security Level | Use Case |
---|---|---|---|---|
HS256 HMAC-SHA256 | 32+ bytes | 256 bits | Standard | General purpose, widely supported |
HS384 HMAC-SHA384 | 48+ bytes | 384 bits | High | Sensitive applications, compliance |
HS512 HMAC-SHA512 | 64+ bytes | 512 bits | Maximum | High-security environments |
Implementation Examples
See how to properly use JWT secrets in popular frameworks and languages
Node.js with jsonwebtoken
// .env
JWT_SECRET=your-base64-encoded-secret-here
// main.js
"keyword">import { jwt } "keyword">from 'jsonwebtoken';
// Load your secret key "keyword">from environment variables
"keyword">const secretKey = process.env.JWT_SECRET; // e.g., 'your-base64-encoded-secret-here'
"keyword">const payload = {
iss: 'my-app',
sub: 'user123',
name: 'John Doe',
admin: true
};
// ✍️ Signing a token
"keyword">const token = jwt.sign(payload, secretKey, {
algorithm: 'HS256',
expiresIn: '1h'
});
console.log('Generated Token:', token);
// ✅ Verifying a token
"keyword">try {
"keyword">const decoded = jwt.verify(token, secretKey, { algorithms: ['HS256'] });
console.log('Decoded Payload:', decoded);
} "keyword">catch (err) {
console.error('Invalid token:', err.message);
}
Python with PyJWT
# .env
JWT_SECRET=your-base64-encoded-secret-here
# main.py
import jwt
import os
import base64
from datetime import datetime, timedelta, timezone
# Load your secret key and decode it from Base64 to bytes
secret_key_b64 = os.getenv('JWT_SECRET') # e.g., 'your-base64-encoded-secret-here'
secret_key = base64.b64decode(secret_key_b64)
payload = {
'iss': 'my-app',
'sub': 'user123',
'name': 'Jane Doe',
'iat': datetime.now(timezone.utc),
'exp': datetime.now(timezone.utc) + timedelta(hours=1)
}
# ✍️ Encoding (signing) a token
token = jwt.encode(payload, secret_key, algorithm='HS256')
print(f"Generated Token: {token}")
# ✅ Decoding (verifying) a token
try:
decoded = jwt.decode(token, secret_key, algorithms=['HS256'])
print(f"Decoded Payload: {decoded}")
except jwt.InvalidTokenError as e:
print(f"Invalid token: {e}")
}
PHP with Firebase/JWT
# .env
JWT_SECRET=your-base64-encoded-secret-here
// main.php
<?php
require_once('vendor/autoload.php');
use FirebaseJWTJWT;
use FirebaseJWTKey;
// Load your secret key from an environment variable
// The key should be the raw bytes, so we decode the Base64 string
$secretKey = base64_decode(getenv('JWT_SECRET'));
$issuedAt = time();
$expire = $issuedAt + 3600; // 1 hour
$issuer = "my-app";
$payload = [
'iss' => $issuer,
'iat' => $issuedAt,
'exp' => $expire,
'sub' => 'user123',
'name' => 'Jim Doe'
];
// ✍️ Encoding (signing) a token
$token = JWT::encode($payload, $secretKey, 'HS256');
echo "Generated Token: " . $token . "
";
// ✅ Decoding (verifying) a token
try {
$decoded = JWT::decode($token, new Key($secretKey, 'HS256'));
print_r($decoded);
} catch (Exception $e) {
echo 'Invalid token: ', $e->getMessage(), "
";
}
Go with Golang-jwt
// .env
JWT_SECRET=your-base64-encoded-secret-here
// main.go
package main
import (
"fmt"
"os"
"time"
"github.com/golang-jwt/jwt/v5"
)
func main() {
// Load your secret key from environment variables.
// In a real app, this should be the raw bytes. For convenience,
// we are using the Base64 string here but it's better to load raw bytes.
var secretKey = []byte(os.Getenv("JWT_SECRET")) // e.g., 'your-secret-key-as-string'
// or base64.StdEncoding.DecodeString(...)
// ✍️ Creating and signing a token
claims := jwt.MapClaims{
"iss": "my-app",
"sub": "user123",
"name": "Go Gopher",
"admin": true,
"exp": time.Now().Add(time.Hour * 1).Unix(),
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenString, err := token.SignedString(secretKey)
if err != nil {
panic(err)
}
fmt.Printf("Generated Token: %v
", tokenString)
// ✅ Parsing and validating a token
parsedToken, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
// Validate the signing algorithm
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return secretKey, nil
})
if err != nil {
fmt.Printf("Invalid token: %v
", err)
} else if claims, ok := parsedToken.Claims.(jwt.MapClaims); ok && parsedToken.Valid {
fmt.Printf("Decoded Claims: Name=%v, Admin=%v
", claims["name"], claims["admin"])
} else {
fmt.Println("Invalid token")
}
}