Qpki
Post-Quantum X.509 PKI toolkit - PQC & Hybrid Certificates in Go
Install / Use
/learn @qpki/QpkiREADME
title: "Quick Start" description: "Get started with QPKI - Post-Quantum X.509 PKI in Go"
QPKI
Post-Quantum X.509 PKI in Go
QPKI is a quantum-safe PKI toolkit to help organizations prepare for post-quantum cryptography (PQC) with interoperable, standards-compliant certificates.
For education and prototyping — Learn PKI concepts, experiment with PQC migration, and test crypto-agility. See Qlab for step-by-step tutorials.
Features
- State-of-the-art X.509 certificates (RFC 5280 compliant)
- Post-Quantum Cryptography (PQC) support via ML-DSA, SLH-DSA and ML-KEM
- CSR generation for all algorithms including RFC 9883 ML-KEM attestation
- Catalyst certificates (ITU-T X.509 Section 9.8) - dual keys via extensions
- Composite certificates (IETF draft-13, DRAFT) - dual keys bound together
- Hybrid certificates (classical + PQC via combined or separate modes)
- SSH Certificates (OpenSSH format) - user and host certificate issuance (classical algorithms)
- CMS Signatures & Encryption (RFC 5652) - sign and encrypt with PQC
- Crypto-agility - seamless migration between algorithms (ECDSA → ML-DSA)
- Profiles (certificate templates) - define certificate policies in YAML
- Credentials - group certificates with coupled lifecycle
- HSM support via PKCS#11
- Cross-validated with external implementations (OpenSSL, BouncyCastle)
- CLI-first - simple, scriptable, no database required
- PQC via Cloudflare CIRCL — FIPS 203/204/205 implementations, NIST ACVP test vectors validated
- Pure Go by default - CGO optional (only for HSM/PKCS#11)
Supported Algorithms
Classical
| Algorithm | Security | Notes | |-----------|----------|-------| | ECDSA (P-256, P-384, P-521) | ~128/192/256-bit | NIST curves, P-384 recommended | | EdDSA (Ed25519, Ed448) | ~128/224-bit | Fast, constant-time | | RSA (2048, 4096) | ~112/140-bit | Legacy compatibility |
EC keys support both ECDSA (signature) and ECDH (key agreement) depending on certificate keyUsage.
Post-Quantum
| Algorithm | Security | Notes | |-----------|----------|-------| | ML-DSA-44/65/87 | NIST Level 1/3/5 | FIPS 204, lattice-based | | SLH-DSA-128/192/256 | NIST Level 1/3/5 | FIPS 205, hash-based | | ML-KEM-512/768/1024 | NIST Level 1/3/5 | FIPS 203, key encapsulation |
Classical security levels reflect resistance to classical attacks only. Post-quantum algorithms are designed to remain secure against quantum adversaries.
Installation
Requirements
- Go 1.25 or later (only for building from source)
- No CGO required for standard usage
- CGO required only for HSM/PKCS#11 support (optional)
- No system dependencies (OpenSSL not required, pure Go)
Quick Install (recommended)
Linux / macOS:
curl -sSL get.qpki.io | sh
Windows (PowerShell):
irm https://qpki.io/install.ps1 | iex
Download pre-built binaries
Download the latest release for your platform from GitHub Releases.
Linux / macOS:
# Download (replace VERSION, OS, and ARCH as needed)
curl -LO https://github.com/qpki/qpki/releases/latest/download/qpki_VERSION_OS_ARCH.tar.gz
# Extract
tar -xzf qpki_*.tar.gz
# Install
sudo mv qpki /usr/local/bin/
# Verify
qpki --version
Available platforms:
| OS | Architecture | File |
|----|--------------|------|
| Linux | amd64 | qpki_VERSION_linux_amd64.tar.gz |
| Linux | arm64 | qpki_VERSION_linux_arm64.tar.gz |
| macOS | Intel | qpki_VERSION_darwin_amd64.tar.gz |
| macOS | Apple Silicon | qpki_VERSION_darwin_arm64.tar.gz |
| macOS | Universal | qpki_VERSION_darwin_all.tar.gz |
| Windows | amd64 | qpki_VERSION_windows_amd64.zip |
Linux packages:
# Debian/Ubuntu
sudo dpkg -i qpki_VERSION_linux_amd64.deb
# RHEL/Fedora
sudo rpm -i qpki_VERSION_linux_amd64.rpm
Install via Homebrew (macOS)
brew tap qpki/qpki
brew install qpki
Verify release signatures
All releases are signed with GPG. To verify:
# Import public key
gpg --keyserver keyserver.ubuntu.com --recv-keys 39CD0BF9647E3F56
# Download checksums and signature
curl -LO https://github.com/qpki/qpki/releases/download/vX.Y.Z/checksums.txt
curl -LO https://github.com/qpki/qpki/releases/download/vX.Y.Z/checksums.txt.sig
# Verify signature
gpg --verify checksums.txt.sig checksums.txt
Build from source
Requires Go 1.25 or later.
# Clone and build
git clone https://github.com/qpki/qpki.git
cd qpki
go build -o qpki ./cmd/qpki
# Or install directly to GOPATH/bin
go install github.com/qpki/qpki/cmd/qpki@latest
Verify installation
qpki --version
qpki --help
Quick Start
Initialize a Root CA
# Create a CA with ECDSA P-384 (recommended)
qpki ca init --profile ec/root-ca --ca-dir ./root-ca --var cn="My Root CA"
# → root-ca/{ca.crt, private/ca.key, certs/, crl/, index.txt, serial}
# Create a hybrid CA (ECDSA + ML-DSA, ITU-T X.509 Section 9.8)
qpki ca init --profile hybrid/catalyst/root-ca --ca-dir ./hybrid-ca --var cn="Hybrid Root CA"
# Create a pure PQC CA (ML-DSA-87)
qpki ca init --profile ml/root-ca --ca-dir ./pqc-ca --var cn="PQC Root CA"
Create a Subordinate CA
# Create a subordinate/issuing CA signed by the root
qpki ca init --profile ec/issuing-ca --ca-dir ./issuing-ca \
--parent ./root-ca --var cn="Issuing CA"
This creates a complete CA structure with:
ca.crt- Subordinate CA certificatechain.crt- Full certificate chain (sub CA + root)private/ca.key- Subordinate CA private key
Generate Keys
Generate private key files. The public key is mathematically derived from the private key and can be extracted using qpki key pub.
# Generate an ECDSA key
qpki key generate --algorithm ecdsa-p256 --out key.pem
# Generate an ML-DSA-65 (PQC lattice-based) key
qpki key generate --algorithm ml-dsa-65 --out ml-dsa-key.pem
# Generate an SLH-DSA-128f (PQC hash-based) key
qpki key generate --algorithm slh-dsa-128f --out slh-dsa-key.pem
# Generate with passphrase protection
qpki key generate --algorithm ecdsa-p384 --out key.pem --passphrase mysecret
# Extract public key from private key
qpki key pub --key key.pem --out key.pub
Generate Certificate Signing Requests
When using --keyout, the private key is generated alongside the CSR. Use --key to create a CSR from an existing key.
# Generate NEW key pair + CSR
qpki csr gen --algorithm ecdsa-p256 --keyout server.key --cn server.example.com --out server.csr
# CSR from EXISTING key (no key generation)
qpki csr gen --key existing.key --cn server.example.com --out server.csr
# PQC CSR (ML-DSA)
qpki csr gen --algorithm ml-dsa-65 --keyout mldsa.key --cn alice@example.com --out mldsa.csr
# ML-KEM CSR with RFC 9883 attestation
qpki csr gen --algorithm ml-kem-768 --keyout kem.key --cn alice@example.com \
--attest-cert sign.crt --attest-key sign.key --out kem.csr
# Hybrid CSR (ECDSA + ML-DSA dual signatures)
qpki csr gen --algorithm ecdsa-p256 --keyout classical.key \
--hybrid ml-dsa-65 --hybrid-keyout pqc.key --cn example.com --out hybrid.csr
Issue Certificates
Certificates are always issued from a CSR (Certificate Signing Request).
For direct issuance with key generation, use qpki credential enroll instead.
# From classical CSR with variables
qpki cert issue --ca-dir ./myca --profile ec/tls-server \
--csr server.csr --out server.crt \
--var cn=api.example.com \
--var dns_names=api.example.com,api-v2.example.com
# Using a variables file
qpki cert issue --ca-dir ./myca --profile ec/tls-server \
--csr server.csr --var-file vars.yaml
# From PQC signature CSR (ML-DSA, SLH-DSA)
qpki cert issue --ca-dir ./myca --profile ml/tls-server \
--csr mldsa.csr --out server.crt \
--var cn=pqc.example.com
# From ML-KEM CSR (requires RFC 9883 attestation for verification)
qpki cert issue --ca-dir ./myca --profile ml-kem/client \
--csr kem.csr --out kem.crt \
--attest-cert sign.crt --var cn=client@example.com
# From Hybrid CSR (classical + PQC dual signatures)
qpki cert issue --ca-dir ./myca --profile hybrid/catalyst/tls-server \
--csr hybrid.csr --out server.crt \
--var cn=hybrid.example.com
Inspect & Verify
# Show certificate details
qpki inspect certificate.crt
# Show key information
qpki inspect private-key.pem
# Verify certificate chain
qpki cert verify server.crt --ca ./myca/ca.crt
# Verify with CRL revocation check
qpki cert verify server.crt --ca ./myca/ca.crt --crl ./myca/crl/ca.crl
# List all issued certificates
qpki cert list --ca-dir ./myca
# List only valid certificates
qpki cert list --ca-dir ./myca --status valid
Sign & Encrypt with CMS
# Sign a document (detached signature)
qpki cms sign --data doc.pdf --cert signer.crt --key signer.key --out doc.p7s
# Verify signature
qpki cms verify doc.p7s --data doc.pdf --ca ca.crt
# Encrypt for recipient (supports ECDH, RSA, ML-KEM)
qpki cms encrypt --recipient bob.crt --in secr
