
Toolbox PKI lato client che decodifica artefatti X.509, CSR, chain, CRL, PKCS#7 e PKCS#12, visualizza ASN.1, converte formati e genera certificati self-signed nel browser.
Una toolbox self-hosted, 100% client-side per artefatti PKI: certificati X.509, CSR PKCS#10, catene, CRL, bundle PKCS#7 e PKCS#12, ASN.1 grezzo, conversione di formato, fingerprint ed emissione di certificati. Un'alternativa rispettosa della privacy e self-hostable ai decoder di certificati online.
Demo live: https://pki-toolbox.youkyi.net (la demo è la stessa build statica che puoi self-hostare qui sotto; nulla di ciò che incolli lascia il tuo browser).
Ogni byte viene analizzato all'interno del tuo browser con @peculiar/x509
e pkijs. Nulla viene mai
caricato, il backend distribuisce solo file statici. Non devi fidarti sulla
parola: vedi Privacy verificabile qui sotto.
| Strumento | Categoria | Descrizione |
|---|
| Decoder di certificati | Decodifica | Ogni campo di un certificato X.509: subject, issuer, validità, SAN, key usage, fingerprint |
| Decoder di CSR | Decodifica | Subject, chiave pubblica, algoritmo di firma ed estensioni richieste di una richiesta PKCS#10 |
| Decoder di catene | Decodifica | Suddivide un bundle PEM concatenato in una catena ordinata e verifica ogni collegamento issuer-to-subject |
| Decoder di CRL | Decodifica | Voci revocate, date e motivi di revoca |
| Decoder PKCS#7 | Decodifica | Ogni certificato trasportato da un bundle PKCS#7 / CMS |
| Decoder PKCS#12 | Decodifica | Apre file .p12 / .pfx protetti da password |
| Fingerprint | Ispezione | SHA-1 / SHA-256 / SHA-512 del DER |
| Visualizzatore ASN.1 | Ispezione | Albero tag/length/value espandibile di qualsiasi artefatto DER |
| Conversione di formato | Conversione | PEM ↔ DER ↔ PKCS#7 |
| Certificato self-signed | Generazione | Certificato self-signed e coppia di chiavi (RSA / EC / Ed25519) tramite WebCrypto |
| Firma da una CA | Generazione | Emette un certificato da una CA esistente: nuova coppia di chiavi o CSR, leaf o intermediate, con fullchain pronta all'uso |
Il catalogo vive in un unico registry (src/lib/tools.ts) che guida la
navbar e la griglia della home.
Attorno agli strumenti stessi:
src/lib/pki/detect.ts) e si apre
nello strumento che lo legge./ posiziona il cursore
nell'input.L'affermazione "non lascia mai il tuo browser" è verificabile dall'interno della pagina:
connect-src della pagina dalla policy con cui è stata servita, conta le
richieste in grado di trasportare dati all'esterno da quando hai incollato, ed
esegue un tentativo live che il browser rifiuta davanti a te, citando la
direttiva che lo ha bloccato.Esegui sempre un tag di release fissato e immutabile (vX.Y.Z), mai latest:
un tag mobile non può essere verificato né ripristinato. Per la garanzia più
forte, fissa il digest dell'immagine (...@sha256:...).
docker run -p 8080:8080 ghcr.io/youkyi/pki-toolbox:v2.2.0
Poi apri http://localhost:8080.
Ogni release è pubblicata, sotto lo stesso tag immutabile vX.Y.Z, su:
| Registry | Immagine |
|---|---|
| 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
Il repository include un docker-compose.yml completamente rafforzato
(filesystem root in sola lettura, capability rimosse, limiti di memoria e CPU);
usa direttamente quel file invece di questo esempio minimale.
L'immagine è costruita da nginx:alpine-slim, pesa circa 25 MB, ascolta sulla
porta non privilegiata 8080 e gira come utente non-root.
Richiede Node 24 (la versione con cui l'immagine e la CI compilano) e
pnpm 11. La versione esatta di pnpm è fissata dal campo packageManager di
package.json, quindi corepack enable è sufficiente per ottenerla.
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 in puro
HTML/JS: ogni route è prerenderizzata e non c'è runtime Node in produzione.src/lib/pki/, senza
import Svelte: parse.ts, chain.ts, crl.ts, pkcs7.ts, pkcs12.ts,
asn1.ts, convert.ts, format.ts, pem.ts, oids.ts, detect.ts,
generate.ts e sign.ts. Ogni route sotto src/routes/ è un sottile shell
UI attorno a esse.@peculiar/x509 v2 costruisce i suoi oggetti tramite tsyringe, che richiede
un polyfill dei metadata Reflect lato consumer, quindi @abraham/reflection
viene importato prima di esso in ogni modulo che usa la libreria.pkijs, il cui engine Web Crypto è
registrato una volta in src/lib/pki/engine.ts.tests/pki/ (Vitest) e i test browser in e2e/
(Playwright). Le fixture sono root pubbliche reali (ISRG Root X1/X2) più una
catena EC e una CSR generate, vedi scripts/generate-fixtures.mjs.<meta> con connect-src 'none'; nginx aggiunge
frame-ancestors 'none', X-Frame-Options, X-Content-Type-Options,
Referrer-Policy: no-referrer, una Permissions-Policy restrittiva e gli
header di isolamento cross-origin. La demo Vercel invia lo stesso set di
header (vedi vercel.json).docker-compose.yml incluso aggiunge un filesystem root in sola lettura,
cap_drop: ALL, no-new-privileges e limiti di risorse.trivy fs) sia sull'immagine appena
costruita, che viene anche rifiutata quando il suo OS base è end-of-life,
così un'immagine vulnerabile non viene mai pubblicata. Le licenze sono
scansionate in un passaggio separato e non bloccante.Questo progetto segue il Semantic Versioning e i
Conventional Commits. Le modifiche
rilevanti sono registrate in CHANGELOG.md. Le regole di
contribuzione sono in CONTRIBUTING.md.
CHANGELOG.md, rinomina l'intestazione ## [Unreleased]
con la nuova versione e la data odierna, ad es. ## [1.2.3] - 2026-06-01,
aggiungi sopra una nuova ## [Unreleased] vuota, e aggiorna i riferimenti ai
link in fondo al file."version" in package.json allo stesso numero.main (un conventional commit, ad es. chore(release): 1.2.3)
e push.git tag -a v1.2.3 -m "pki-toolbox v1.2.3"
git push origin v1.2.3
Lint, unit test e test end-to-end girano a ogni push. Gli stadi di scan, build e
release provengono dai componenti condivisi
YouKyi-Infra/ci-infrastructure/ci-catalog (trivy-scan, docker-build,
gitlab-release), fissati per versione in .gitlab-ci.yml.
Un tag vX.Y.Z esegue l'intera catena: scan, build dell'immagine, scan
dell'immagine, push di vX.Y.Z sul registry GitLab e sui mirror pubblici
(ghcr.io, Docker Hub), poi una GitLab Release le cui note sono la sezione
## [X.Y.Z] corrispondente estratta da CHANGELOG.md (una sezione vuota fa
fallire il job invece di pubblicare note vuote).
Un push su main esegue la stessa pipeline meno lo stadio di release, e il job
dell'immagine gira solo quando è cambiato un file che influisce sulla build,
così un push di soli docs o config non ricostruisce l'immagine.
Le dipendenze sono mantenute aggiornate da Renovate,
che estende il preset condiviso Renovate-Bot/renovate-config
(vedi renovate.json).