Files
skills/docs/security-stack/crypto/crypto-rsa/src/keys/parse-jwk.md
2026-05-29 08:20:56 +01:00

2.5 KiB

keys/parse-jwk

Purpose

Parses RSA JWKs per RFC 7517 §6.3.1 (public) and §6.3.2 (private). Accepts the JWK as a plain JS object literal, as a JSON string, or as a Uint8Array of UTF-8 JSON bytes — all common ways the format is carried in the wild (headers vs. bodies vs. binary protocol fields).

JWK is the JOSE / OIDC / WebAuthn canonical RSA representation and the required input format for @suaveplan/jws's RSA algorithms (RS256, PS256, etc.).

Features

  • Triple-form input (RsaJwk object / JSON string / UTF-8 bytes).
  • Explicit kty: "RSA" enforcement (UNSUPPORTED_FORMAT otherwise).
  • Base64url decode per RFC 7515 §2 (URL-safe alphabet, no padding) via @suaveplan/crypto-utils.
  • Private-form requires every CRT field (d, p, q, dp, dq, qi) — partial private JWKs reject with INVALID_KEY.

Usage: Basic Example

import { parseRsaPublicKeyJwk } from "@suaveplan/crypto-rsa";

const key = parseRsaPublicKeyJwk({
    kty: "RSA",
    n: "0vx7agoeb...",
    e: "AQAB",
});

Usage: Advanced Example

import {
    parseRsaPrivateKeyJwk,
    parseRsaPublicKeyJwk,
} from "@suaveplan/crypto-rsa";

const fromJson = parseRsaPublicKeyJwk(jsonString);
const fromBytes = parseRsaPublicKeyJwk(utf8Bytes);

const privateKey = parseRsaPrivateKeyJwk({
    kty: "RSA",
    n, e, d, p, q, dp, dq, qi,
});

API Reference

parseRsaPublicKeyJwk(input: RsaJwk | string | Uint8Array): RsaPublicKey

Decodes the JWK, validates kty === "RSA", and decodes n + e.

parseRsaPrivateKeyJwk(input: RsaJwk | string | Uint8Array): RsaPrivateKey

Same as above plus the CRT parameters. Every field is mandatory.

Both throw CRYPTO_RSA.UNSUPPORTED_FORMAT for non-RSA kty, and CRYPTO_RSA.INVALID_KEY for missing members, empty values, or invalid base64url.

Implementation Notes

The JWK input may be an RsaJwk literal (already-typed), a JSON string (common in headers), or a UTF-8 Uint8Array (common in network framing). Internally we normalise to a plain object before extracting members so the validation logic stays one path.

Base64url decoding goes through @suaveplan/crypto-utils's fromBase64Url which accepts both padded and unpadded inputs; JWA mandates unpadded, but some implementations leak padding in the wild and we accept that gracefully.

The JWK private-key qi member is RFC 7517's name for what RFC 8017 calls qInv (the CRT coefficient q⁻¹ mod p). The canonical RsaPrivateKey shape uses qInv for consistency with RFC 8017, so we translate qi → qInv in the parser.