first commit
This commit is contained in:
80
docs/security-stack/crypto/crypto-rsa/src/keys/parse-jwk.md
Normal file
80
docs/security-stack/crypto/crypto-rsa/src/keys/parse-jwk.md
Normal 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.
|
||||
Reference in New Issue
Block a user