pkijs.com logo

@blamejs/pki — pure-JavaScript PKI toolkit for Node.js

X.509 certificates, ASN.1/DER, CMS, OCSP, CRLs and PKCS formats, with a fail-closed codec, post-quantum algorithms alongside the classical ones, and no npm runtime dependencies.
Zero npm dependencies PQC-first Fail-closed DER CommonJS, no transpilation Apache-2.0

Every page in this reference is generated from the toolkit's own source comments. Zero npm runtime dependencies — the cryptography runs on Node's native node:crypto (classical and FIPS post-quantum), nothing vendored.

Quick start

npm install @blamejs/pki
var pki = require("@blamejs/pki");

var cert = pki.schema.x509.parse(pemText);
cert.subject.dn;                 // "CN=example.com, O=Example"
cert.validity.notAfter;          // Date
cert.signatureAlgorithm.name;    // "sha256WithRSAEncryption"
TipParse without knowing the format first: pki.schema.parse(der) detects which of the toolkit's registered formats the bytes encode — certificate, CRL, CSR, CMS, OCSP, PKCS#8, PKCS#12, timestamp token, and the rest — and routes to the owning parser. pki.schema.all() lists the registered formats.

Common tasks

Read a certificate's subject, validity and extensions

var cert = pki.schema.x509.parse(pemOrDer);
cert.subject.dn;          // "CN=example.com, O=Example"
cert.validity.notAfter;   // Date
cert.serialNumberHex;     // "75cb4dae..."
cert.extensions;          // [ { oid, name: "subjectAltName", critical, value }, ... ]

Full reference for this namespace

Verify a CMS / PKCS#7 signature

var res = await pki.cms.verify(signedDer, { trustAnchors: [rootDer] });
res.valid;                // every signer verified
res.eContentType;         // "1.2.840.113549.1.7.1" -- the encapsulated type, as an OID
res.signers[0].ok;        // this signer verified
res.trusted;              // the signers chained to an anchor

Full reference for this namespace

Validate a certificate chain to a trust anchor

// Two shapes to get right. The path runs ANCHOR-ADJACENT FIRST and the TARGET LAST --
// the reverse of how a chain is usually written. And the anchor is an object built from the
// parsed root, not the root's DER (both take trustAnchors; cms.verify above passed an array, this
// passes a single anchor).
var root = pki.schema.x509.parse(rootDer);
var res = await pki.path.validate([intermediate, leaf], {
  trustAnchors: {
    name: root.subject,
    publicKey: root.subjectPublicKeyInfo.bytes,
    algorithm: root.subjectPublicKeyInfo.algorithm.oid,   // the anchor's own key algorithm
  },
  time: new Date(),
});
res.valid;                // true -- the verb throws on malformed input, so this is a real verdict
res.revocationChecked;    // what was actually checked, not what was assumed
res.results[0].checks;    // [ { name: "signature", ok }, { name: "nameChaining", ok }, ... ]

Full reference for this namespace

Check whether a certificate has been revoked

var crl = pki.schema.crl.parse(crlDer);
var revoked = crl.revokedCertificates.filter(function (r) {
  return r.serialNumber === cert.serialNumber;   // both are BigInt
});
revoked[0] && revoked[0].revocationDate;         // Date

Full reference for this namespace

Create a certificate signing request

// sign(spec, key, opts) -- the signing key is the SECOND argument, not an option
var csrPem = await pki.csr.sign(
  { subject: "CN=example.com", subjectPublicKey: spkiDer },
  { key: keyDer },
  { pem: true }
);

Full reference for this namespace

Open a PKCS#12 keystore

// The password is a positional argument; omitting it is not the empty password
var store = await pki.pkcs12.open(p12Bytes, "changeit");
store.macVerified;        // the integrity MAC checked out

Full reference for this namespace

Requirements

Node.js LTS, as shipped. The package is CommonJS and is published without a build step, so require("@blamejs/pki") loads the same JavaScript that lives in the repository. There is no TypeScript compilation, no bundler, and no transpilation between the source and the tarball. Cryptography runs on Node's built-in node:crypto, which covers the classical algorithms and the FIPS post-quantum ones, so no native module is compiled at install time.

Design tenets

Namespaces