
Client-side PKI toolbox that decodes X.509, CSR, chain, CRL, PKCS#7 and PKCS#12 artifacts, views ASN.1, converts formats, and generates self-signed certificates in the browser.
A self-hosted, 100 % client-side toolbox for PKI artefacts: X.509 certificates, PKCS#10 CSRs, chains, CRLs, PKCS#7 and PKCS#12 bundles, raw ASN.1, format conversion, fingerprints and certificate issuance. A privacy-respecting, self-hostable replacement for online certificate decoders.
Live demo: https://pki-toolbox.youkyi.net (the demo is the same static build you can self-host below; nothing you paste leaves your browser).
Every byte is parsed inside your browser with @peculiar/x509
and pkijs. Nothing is ever
uploaded, the backend only ships static files. You do not have to take that on
trust: see Checkable privacy below.
| Tool | Category | Description |
|---|---|---|
| Certificate decoder | Decoding | Every field of an X.509 certificate: subject, issuer, validity, SANs, key usage, fingerprints |
| CSR decoder | Decoding | Subject, public key, signature algorithm and requested extensions of a PKCS#10 request |
| Chain decoder | Decoding | Splits a concatenated PEM bundle into an ordered chain and verifies every issuer-to-subject link |
| CRL decoder | Decoding | Revoked entries, dates and revocation reasons |
| PKCS#7 decoder | Decoding | Every certificate carried by a PKCS#7 / CMS bundle |
| PKCS#12 decoder | Decoding | Opens password-protected .p12 / .pfx files |
| Fingerprints | Inspection | SHA-1 / SHA-256 / SHA-512 of the DER |
| ASN.1 viewer | Inspection | Expandable tag/length/value tree of any DER artefact |
| Format conversion | Conversion | PEM ↔ DER ↔ PKCS#7 |
| Self-signed certificate | Generation | Self-signed certificate and key pair (RSA / EC / Ed25519) via WebCrypto |
| Sign from a CA | Generation | Issues a certificate from an existing CA: new key pair or CSR, leaf or intermediate, with a ready-to-use fullchain |
The catalogue lives in a single registry (src/lib/tools.ts) that drives the
navbar and the home grid.
Around the tools themselves:
src/lib/pki/detect.ts) and opens in the tool
that reads it./ puts the caret in the input.The claim "it never leaves your browser" is verifiable from inside the page:
connect-src directive from the policy it was served with, counts the
requests able to carry data out since you pasted, and runs a live attempt the
browser refuses in front of you, quoting the directive that blocked it.Always run a pinned, immutable release tag (vX.Y.Z), never latest: a moving
tag cannot be audited or rolled back. For the strongest guarantee, pin the
image digest (...@sha256:...).
docker run -p 8080:8080 ghcr.io/youkyi/pki-toolbox:v2.2.0
Then open http://localhost:8080.
Each release is published, under the same immutable vX.Y.Z tag, to:
| Registry | Image |
|---|---|
| GitHub Container Registry | ghcr.io/youkyi/pki-toolbox |
| Docker Hub | youkyi/pki-toolbox |
docker pull ghcr.io/youkyi/pki-toolbox:v2.2.0 # or
docker pull youkyi/pki-toolbox:v2.2.0
services:
pki-toolbox:
image: ghcr.io/youkyi/pki-toolbox:v2.2.0
ports:
- '8080:8080'
restart: unless-stopped
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
read_only: true
docker compose up -d
The repository ships a fully hardened docker-compose.yml (read-only root
filesystem, dropped capabilities, memory and CPU limits); use that file
directly rather than this minimal example.
The image is built from nginx:alpine-slim, weighs about 25 MB, listens on the
non-privileged port 8080 and runs as a non-root user.
Requires Node 24 (the version the image and CI build with) and pnpm 11.
The exact pnpm version is pinned by the packageManager field of
package.json, so corepack enable is enough to get it.
pnpm install
pnpm dev # dev server on http://localhost:5173
pnpm test # unit tests, single run (Vitest)
pnpm test:unit # the same tests, in watch mode
pnpm test:e2e # end-to-end tests (Playwright)
pnpm test:e2e:ui # the same, in the Playwright UI
pnpm check # svelte-check / TypeScript
pnpm lint # Prettier + ESLint
pnpm format # rewrite files with Prettier
pnpm build # static build into ./build
pnpm preview # serve ./build locally
docker build -t pki-toolbox .
docker run -p 8080:8080 pki-toolbox
adapter-static to plain
HTML/JS: every route is prerendered and there is no Node runtime in
production.src/lib/pki/, with no
Svelte import: parse.ts, chain.ts, crl.ts, pkcs7.ts, pkcs12.ts,
asn1.ts, convert.ts, format.ts, pem.ts, oids.ts, detect.ts,
generate.ts and sign.ts. Each route under src/routes/ is a thin UI
shell around them.@peculiar/x509 v2 builds its objects through tsyringe, which needs a
Reflect metadata polyfill on the consumer side, so @abraham/reflection is
imported ahead of it in every module that uses the library.pkijs, whose Web Crypto engine is registered
once in src/lib/pki/engine.ts.tests/pki/ (Vitest) and browser tests in e2e/
(Playwright). Fixtures are real public roots (ISRG Root X1/X2) plus a
generated EC chain and CSR, see scripts/generate-fixtures.mjs.