How to Generate a JWT Token (HS256/HS384/HS512) — No Library, No Server
By Rui Barreira · Last updated: 13 June 2026
A JSON Web Token (JWT) is a compact, URL-safe way to represent claims between two parties. You can generate signed JWT tokens entirely in your browser — no server, no library installation required — using the Web Crypto API. Use brevio JWT Generator to generate HS256, HS384, or HS512 tokens with custom claims, set expiry, and copy the result.
JWT Structure Explained
A JWT consists of three base64url-encoded parts separated by dots: header.payload.signature.
- Header: Declares the token type and signing algorithm. Example:
{"alg": "HS256", "typ": "JWT"} - Payload: Contains claims — statements about the subject plus metadata. Standard claims are defined by RFC 7519; you can add any custom claims.
- Signature: The HMAC or RSA signature of
base64url(header).base64url(payload). Prevents tampering — changing any byte in the header or payload invalidates the signature.
The three parts are base64url-encoded (not encrypted). Anyone who has the token can decode the header and payload by base64-decoding them. The token proves the content has not been modified, but the payload is not secret.
Standard Claims Explained
| Claim | Full Name | Purpose |
|---|---|---|
| iss | Issuer | Who issued the token (your app name or URL) |
| sub | Subject | The user or entity the token represents (user ID) |
| aud | Audience | Who the token is intended for (target API) |
| iat | Issued At | Unix timestamp of when the token was created |
| exp | Expiration | Unix timestamp after which the token is invalid |
| nbf | Not Before | Unix timestamp before which the token is invalid |
| jti | JWT ID | Unique identifier for this specific token instance |
The exp claim is the most important for security. A token without an expiry is valid forever — if stolen, it cannot be revoked without a token blocklist. Short-lived tokens (15 min to 1 hour) limit the damage if a token is compromised.
HMAC vs RSA Algorithms
The alg header determines how the signature is created and verified.
- HS256/HS384/HS512 (HMAC-SHA): Uses a single shared secret for both signing and verification. Both parties must know the secret. Fast, simple, good for monolithic apps where the same service issues and verifies tokens.
- RS256/RS384/RS512 (RSA-SHA): Asymmetric — private key signs, public key verifies. The public key can be shared openly (e.g., via a JWKS endpoint) so other services can verify tokens without access to the signing key. Required for distributed systems and OAuth 2.0 / OpenID Connect.
- ES256/ES384/ES512 (ECDSA): Asymmetric like RSA but with smaller keys and faster operations. Preferred over RSA for new implementations.
The brevio JWT Generator implements HMAC algorithms (HS256/HS384/HS512) using the browser's Web Crypto API. For RSA/ECDSA, use a dedicated library or your auth provider's SDK.
How to Generate a JWT in Your Browser
- Open brevio JWT Generator.
- Enter your subject (sub) — typically a user ID like
user123or a UUID. - Set the issuer (iss) — your application name or URL.
- Choose an expiry — 1 hour for access tokens, longer for refresh tokens.
- Enter your secret — use a long, random string. Never use a predictable value in production.
- Add custom claims (optional) — any JSON object, e.g.
{"role": "admin"}. - Click Generate JWT and copy the token.
Base64URL Encoding Explained
JWTs use base64url encoding, a URL-safe variant of standard base64. The differences: + is replaced with -, / with _, and padding = is removed. This makes JWTs safe to include in URLs and HTTP headers without percent-encoding.
Security Advice
- Never put sensitive data in the payload. The payload is base64-encoded, not encrypted. Passwords, credit card numbers, and API keys must not appear in JWT claims.
- Use strong secrets. HMAC keys should be at least 256 bits (32 bytes) of random data.
openssl rand -hex 32generates a suitable key. - Set short expiry for access tokens. 15 minutes to 1 hour is common. Use refresh tokens for session persistence.
- Never log tokens. JWTs in log files are credentials waiting to be stolen. Redact them in all logging and error reporting systems.
- Validate all claims on the server. Check
exp,iss, andaudon every request — not just the signature.
DevTools Verification
Open DevTools and check the Network tab while generating a JWT. No POST requests are made — the HMAC signing runs via crypto.subtle.sign() in your browser. Your secret and payload are never transmitted.
Command Line Alternative
# Install jwt-cli npm install -g jwt-cli # Generate HS256 token jwt sign --secret mysecret --subject user123 --expiry 1h '{"role":"admin"}'Frequently Asked Questions
- What is the difference between HS256 and RS256?
- HS256 (HMAC-SHA256) uses a single shared secret for both signing and verification — both parties must know the secret. RS256 (RSA-SHA256) uses an asymmetric key pair: the private key signs the token, and the public key verifies it. RS256 is preferred when you need to share the verification key publicly (e.g., microservices verifying tokens issued by an auth server) without exposing the signing key.
- Can I put a password in the JWT payload?
- No. JWT payloads are base64-encoded, not encrypted — anyone who has the token can decode the payload. Never put passwords, API keys, credit card numbers, or other sensitive data in JWT claims. The token is signed (tamper-proof) but not encrypted (not private). If you need to include sensitive data, use JWE (JSON Web Encryption) instead.
- How long should a JWT token be valid?
- Access tokens should be short-lived: 15 minutes to 1 hour is common. Long-lived tokens (24h+) increase the attack window if a token is stolen. Use refresh tokens for session persistence — the refresh token has a longer lifespan but can only be used to obtain new access tokens, not to access resources directly.
- Why does my JWT verification fail even though the secret is correct?
- Common causes: (1) the secret has trailing whitespace or newline characters; (2) the algorithm in the header (alg claim) does not match what the verifier expects; (3) the token has expired (exp claim is in the past); (4) the audience (aud) or issuer (iss) claims do not match what the verifier requires. Check each of these in order.