first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,80 @@
# `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
```ts
import { parseRsaPublicKeyJwk } from "@suaveplan/crypto-rsa";
const key = parseRsaPublicKeyJwk({
kty: "RSA",
n: "0vx7agoeb...",
e: "AQAB",
});
```
## Usage: Advanced Example
```ts
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.