2.3 KiB
keys/parse-pkcs1-private
Purpose
Parses a DER-encoded RSAPrivateKey per RFC 8017 Appendix A.1.2 into the
canonical RsaPrivateKey shape with mandatory CRT parameters
(p, q, dp, dq, qInv). Also exports finalisePrivateKey so the
PKCS#8 and JWK parsers share the same field-positivity validation.
Multi-prime RSA (version == 1 with non-empty otherPrimeInfos) is recognised
but explicitly rejected with CRYPTO_RSA.UNSUPPORTED_FORMAT — the wider
package contract assumes two-prime RSA throughout.
Features
- Strict-DER
RSAPrivateKeyparser viaDerReader. - Version validation (
0two-prime,1multi-prime — both detected; only0accepted). - Multi-prime detection via either
version === 1OR a trailing SEQUENCE (covers conformant and non-conformant emitters). - Per-field positivity gate via
finalisePrivateKey. - Bit-length derivation from
n.toString(2).length.
Usage: Basic Example
import { parseRsaPrivateKeyPkcs1 } from "@suaveplan/crypto-rsa";
const key = parseRsaPrivateKeyPkcs1(derBytes);
// key.n, key.e, key.d, key.p, key.q, key.dp, key.dq, key.qInv, key.bitLength
Usage: Advanced Example
import { finalisePrivateKey } from "@suaveplan/crypto-rsa/keys";
const key = finalisePrivateKey({ n, e, d, p, q, dp, dq, qInv });
API Reference
parseRsaPrivateKeyPkcs1(bytes: Uint8Array): RsaPrivateKey
Throws CryptoRsaError(CRYPTO_RSA.INVALID_KEY) on structural problems and
on any non-positive field. Throws CryptoRsaError(CRYPTO_RSA.UNSUPPORTED_FORMAT)
on multi-prime input.
finalisePrivateKey(inputs): RsaPrivateKey
Validates each of n, e, d, p, q, dp, dq, qInv is > 0n and computes
bitLength from n. Surfaces the same INVALID_KEY error class as the
DER parser.
Implementation Notes
The parser uses both version === 1n and a trailing-SEQUENCE peek to detect
multi-prime keys. Some emitters set version to 0 even when they include
otherPrimeInfos; we reject either flag to avoid silently truncating the
prime set.
The fields are read in fixed order with seq.readInteger() calls; if any
field is missing the underlying DerReader raises INVALID_KEY with a
truncation context. The final seq.assertEnd() ensures no extra fields
slip through (other than the multi-prime trailing SEQUENCE that we explicitly
detected and rejected).