Skip to content

certificateMatchesPrivateKey ​

certificateMatchesPrivateKey ​

Check whether a certificate's subject public key belongs to a private key.

Confirming that an uploaded private key actually matches the certificate it was submitted with is the first thing a key-intake or issuance endpoint must do. This derives the public half of privateKey, exports it as SubjectPublicKeyInfo DER, and compares those bytes against the certificate's own SubjectPublicKeyInfo — the canonical, algorithm-agnostic way to test key ownership. (Comparing JWKs field by field, or signing a probe and verifying it, are both more fragile.)

A private key of a different type — e.g. an ECDSA key against an RSA certificate — simply produces different SPKI DER and returns false, so callers get a single boolean without branching on the kind of mismatch. Reach for matchCertificatePrivateKey when you need the reason a match failed (or a typed failure instead of a thrown error) at a trust boundary.

The comparison is over the exact DER encoding. A certificate whose SubjectPublicKeyInfo pins RSASSA-PSS parameters (rather than the plain rsaEncryption OID that WebCrypto emits) therefore will not match even for the same modulus; such certificates are rare in practice.

ts
function certificateMatchesPrivateKey<TMap extends ExtensionDecoderMap>(
	certificate: ParsedCertificate<TMap> | string | Uint8Array,
	privateKey: CryptoKey,
): Promise<boolean>

Parameters

  • certificate: ParsedCertificate<TMap> | string | Uint8Array — PEM string, DER bytes, or an already-parsed certificate.
  • privateKey: CryptoKey — An extractable private CryptoKey.

Returns — true when the private key's public half matches the certificate's subject public key.

Throws

  • Error — If certificate is malformed, or privateKey is not an extractable private key of a supported type (propagated from derivePublicKey). Use matchCertificatePrivateKey for a typed Result instead of thrown errors.

See also

Examples

ts
const privateKey = await importPkcs8PemOrThrow(keyPem, { kind: 'ecdsa', curve: 'P-256' });
if (!(await certificateMatchesPrivateKey(certificatePem, privateKey))) {
  throw new Error('uploaded key does not match the certificate');
}

Released under the MIT License.