JWK

JWK — keys as JSON

A JSON Web Key (RFC 7517) is a portable JSON representation of a cryptographic key. Every signing, verifying, encrypting, and decrypting operation in unjwt starts with a key — and JWK is the lingua franca for carrying that key through config files, environment variables, databases, and across the wire.

{
  "kty": "oct",
  "k": "GawgguFyGrWKav7AX4VKUg",
  "alg": "HS256",
  "kid": "4c3d-..."
}

Import:

import { generateJWK, importKey, exportKey } from "unjwt/jwk";
// or from the flat barrel:
import { generateJWK } from "unjwt";

Basic usage

The most common operation — create a key:

generate.ts
import { generateJWK } from "unjwt/jwk";

// Symmetric — one JWK
const hmacKey = await generateJWK("HS256");
// { kty: "oct", k: "...", alg: "HS256", kid: "4c3d-..." }

// Asymmetric — a pair
const { privateKey, publicKey } = await generateJWK("RS256");

Every JWK produced by generateJWK() includes:

  • kty — key type ("oct" | "RSA" | "EC" | "OKP").
  • alg — the algorithm it's meant for (e.g. "HS256", "RS256", "Ed25519").
  • kid — an auto-generated UUID, which any JWT signed with this key will carry in its header for routing.

Those three fields are why the rest of the library "just works" — sign(), verify(), encrypt(), decrypt() all read them and do the right thing.

The JWK shape

Every JWK has a kty (key type) field that determines its other properties:

ktyMeaningKey fields
"oct"Symmetric (secret)k (base64url-encoded bytes)
"RSA"RSA keypairn, e, and d/p/q/dp/dq/qi if private
"EC"Elliptic curvecrv, x, y, and d if private
"OKP""Octet Key Pair" (EdDSA / X25519 / Ed448)crv, x, and d if private

A JWK is public if it carries no d (or has no d equivalent for oct); private if it does.

unjwt provides type guards to distinguish:

import { isPublicJWK, isPrivateJWK, isSymmetricJWK } from "unjwt/utils";

if (isSymmetricJWK(key)) {
  /* kty === "oct" */
}
if (isPublicJWK(key)) {
  /* asymmetric, no d */
}
if (isPrivateJWK(key)) {
  /* asymmetric, has d */
}

What you can do with a JWK

Going further