| name | PKI and X.509 |
| description | Expert guidance for Public Key Infrastructure (PKI) and X.509 certificates including certificate structure, DN parsing, CSR generation, certificate signing, revocation (CRL/OCSP), key management, and OpenSSL commands. Use this when working with digital certificates, certificate authorities, or cryptographic key management. |
PKI and X.509 Certificates
Expert assistance with Public Key Infrastructure and X.509 certificate management.
Overview
PKI provides secure digital certificate management:
- X.509: Standard format for public key certificates
- Certificate Authority (CA): Issues and signs certificates
- Certificate Signing Request (CSR): Request for certificate issuance
- Certificate Revocation: CRL and OCSP protocols
- Key Management: Secure generation and storage
X.509 Certificate Structure
Certificate Components
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 4096 (0x1000)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=Example CA, O=Example Org, C=US
Validity
Not Before: Jan 1 00:00:00 2024 GMT
Not After : Jan 1 00:00:00 2025 GMT
Subject: CN=example.com, O=Example Org, C=US
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
X509v3 extensions:
X509v3 Key Usage:
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Subject Alternative Name:
DNS:example.com, DNS:www.example.com
Signature Algorithm: sha256WithRSAEncryption
Distinguished Name (DN)
Components:
- CN (Common Name): example.com
- O (Organization): Example Organization
- OU (Organizational Unit): IT Department
- L (Locality): San Francisco
- ST (State): California
- C (Country): US
- EMAIL: admin@example.com
OpenSSL Commands
Generate Private Keys
# RSA 2048-bit
openssl genrsa -out private.key 2048
# RSA 4096-bit (more secure)
openssl genrsa -out private.key 4096
# Encrypted private key
openssl genrsa -aes256 -out private.key 4096
# ECDSA P-256
openssl ecparam -name prime256v1 -genkey -out private.key
# ECDSA P-384 (more secure)
openssl ecparam -name secp384r1 -genkey -out private.key
Generate Certificate Signing Request (CSR)
# Generate CSR from private key
openssl req -new -key private.key -out request.csr \
-subj "/C=US/ST=California/L=San Francisco/O=Example/CN=example.com"
# Generate key and CSR together
openssl req -new -newkey rsa:4096 -nodes \
-keyout private.key -out request.csr \
-subj "/CN=example.com/O=Example Org/C=US"
# CSR with Subject Alternative Names (SAN)
openssl req -new -key private.key -out request.csr \
-subj "/CN=example.com" \
-addext "subjectAltName=DNS:example.com,DNS:www.example.com,IP:192.168.1.1"
View CSR
# Display CSR details
openssl req -in request.csr -text -noout
# Verify CSR signature
openssl req -in request.csr -verify -noout
Self-Signed Certificates
# Generate self-signed certificate (1 year)
openssl req -x509 -new -key private.key -out cert.pem -days 365 \
-subj "/CN=example.com/O=Example/C=US"
# Self-signed with SAN
openssl req -x509 -new -key private.key -out cert.pem -days 365 \
-subj "/CN=example.com" \
-addext "subjectAltName=DNS:example.com,DNS:*.example.com"
# Generate key and self-signed cert together
openssl req -x509 -newkey rsa:4096 -nodes \
-keyout private.key -out cert.pem -days 365 \
-subj "/CN=Root CA/O=Example/C=US"
Certificate Authority Operations
# Create CA directory structure
mkdir -p ca/{certs,crl,newcerts,private}
touch ca/index.txt
echo 1000 > ca/serial
# Generate CA private key
openssl genrsa -aes256 -out ca/private/ca.key 4096
# Generate CA certificate
openssl req -x509 -new -key ca/private/ca.key \
-out ca/certs/ca.crt -days 3650 \
-subj "/CN=Example CA/O=Example/C=US"
# Sign CSR with CA
openssl ca -config openssl.cnf \
-in request.csr \
-out signed.crt \
-days 365
# Or use x509 for simpler signing
openssl x509 -req -in request.csr \
-CA ca/certs/ca.crt -CAkey ca/private/ca.key \
-CAcreateserial -out signed.crt -days 365 \
-extfile <(printf "subjectAltName=DNS:example.com")
View and Verify Certificates
# View certificate
openssl x509 -in cert.pem -text -noout
# View certificate dates
openssl x509 -in cert.pem -noout -dates
# View certificate subject
openssl x509 -in cert.pem -noout -subject
# View certificate issuer
openssl x509 -in cert.pem -noout -issuer
# Verify certificate against CA
openssl verify -CAfile ca.crt cert.pem
# Verify certificate chain
openssl verify -CAfile ca.crt -untrusted intermediate.crt cert.pem
Convert Certificate Formats
# PEM to DER
openssl x509 -in cert.pem -out cert.der -outform DER
# DER to PEM
openssl x509 -in cert.der -inform DER -out cert.pem -outform PEM
# PEM to PKCS#12 (.p12, .pfx)
openssl pkcs12 -export -out cert.p12 \
-inkey private.key -in cert.pem -certfile ca.crt
# PKCS#12 to PEM
openssl pkcs12 -in cert.p12 -out cert.pem -nodes
Certificate Extensions
Key Usage
digitalSignature - Digital signatures
nonRepudiation - Non-repudiation
keyEncipherment - Encrypt symmetric keys
dataEncipherment - Encrypt data directly
keyAgreement - Key agreement (DH/ECDH)
keyCertSign - Sign certificates (CA only)
cRLSign - Sign CRLs (CA only)
Extended Key Usage (EKU)
serverAuth - TLS server authentication
clientAuth - TLS client authentication
codeSigning - Code signing
emailProtection - S/MIME email protection
timeStamping - Trusted time stamping
OCSPSigning - OCSP response signing
Subject Alternative Names (SAN)
DNS:example.com - Domain name
DNS:*.example.com - Wildcard domain
IP:192.168.1.1 - IP address
email:admin@example.com - Email address
URI:https://example.com - URI
Certificate Revocation
Certificate Revocation List (CRL)
# Generate CRL
openssl ca -config openssl.cnf -gencrl -out crl.pem
# View CRL
openssl crl -in crl.pem -text -noout
# Revoke certificate
openssl ca -config openssl.cnf -revoke cert.pem \
-crl_reason keyCompromise
# Verify certificate against CRL
openssl verify -crl_check -CRLfile crl.pem -CAfile ca.crt cert.pem
Revocation Reasons
unspecified - No specific reason
keyCompromise - Private key compromised
caCompromise - CA key compromised
affiliationChanged - Subject affiliation changed
superseded - Certificate replaced
cessationOfOperation - No longer needed
certificateHold - Temporary suspension
removeFromCRL - Remove from CRL
privilegeWithdrawn - Privileges removed
aACompromise - Attribute authority compromised
Certificate Hierarchy
Root CA
interface RootCA {
subject: DistinguishedName;
keyPair: KeyPair;
certificate: X509Certificate;
validity: {
notBefore: Date;
notAfter: Date; // Typically 10-20 years
};
keyUsage: ['keyCertSign', 'cRLSign'];
basicConstraints: {
cA: true;
pathLenConstraint: undefined; // No limit
};
}
Intermediate CA
interface IntermediateCA {
subject: DistinguishedName;
issuer: DistinguishedName; // Root CA
keyPair: KeyPair;
certificate: X509Certificate;
validity: {
notBefore: Date;
notAfter: Date; // Shorter than root, typically 5-10 years
};
keyUsage: ['keyCertSign', 'cRLSign', 'digitalSignature'];
basicConstraints: {
cA: true;
pathLenConstraint: 0; // Can only sign end-entity certs
};
}
End-Entity Certificate
interface EndEntityCertificate {
subject: DistinguishedName;
issuer: DistinguishedName; // Intermediate or Root CA
keyPair: KeyPair;
certificate: X509Certificate;
validity: {
notBefore: Date;
notAfter: Date; // Typically 1-2 years
};
keyUsage: ['digitalSignature', 'keyEncipherment'];
extendedKeyUsage: ['serverAuth', 'clientAuth'];
subjectAlternativeName: {
dns: string[];
ip: string[];
};
basicConstraints: {
cA: false;
};
}
Node.js Integration
Generate CSR with Node Crypto
import { generateKeyPairSync, createSign } from 'crypto';
import { X509Certificate } from 'crypto';
// Generate key pair
const { publicKey, privateKey } = generateKeyPairSync('rsa', {
modulusLength: 4096,
publicKeyEncoding: {
type: 'spki',
format: 'pem',
},
privateKeyEncoding: {
type: 'pkcs8',
format: 'pem',
},
});
// Parse X.509 certificate
const cert = new X509Certificate(certPem);
console.log(cert.subject);
console.log(cert.issuer);
console.log(cert.validFrom);
console.log(cert.validTo);
console.log(cert.fingerprint256);
Best Practices
- Key Size: Use RSA 4096-bit or ECDSA P-384 for CAs
- Validity Period: Root CA (10-20 years), Intermediate (5-10 years), End-entity (1-2 years)
- Key Storage: Store CA private keys in HSM or KMS
- Certificate Chain: Always verify complete chain of trust
- Revocation: Implement CRL and/or OCSP for revocation checking
- SAN over CN: Use Subject Alternative Names instead of Common Name
- Strong Algorithms: Use SHA-256 or better (avoid SHA-1, MD5)
- Key Usage: Set appropriate key usage and extended key usage
- Path Length: Limit path length in CA certificates
- Audit Trail: Log all certificate operations
Common Operations
Verify Certificate Chain
# Create chain file (cert + intermediate + root)
cat cert.pem intermediate.pem root.pem > chain.pem
# Verify chain
openssl verify -CAfile root.pem -untrusted intermediate.pem cert.pem
Extract Public Key
# From certificate
openssl x509 -in cert.pem -pubkey -noout > public.key
# From private key
openssl rsa -in private.key -pubout -out public.key
Check Certificate-Key Match
# Compare modulus
openssl x509 -in cert.pem -noout -modulus | openssl md5
openssl rsa -in private.key -noout -modulus | openssl md5
# Should match!
Resources
- RFC 5280: X.509 Certificate and CRL Profile
- RFC 2986: PKCS #10 CSR Syntax
- RFC 6960: OCSP Protocol
- OpenSSL Cookbook: https://www.feistyduck.com/books/openssl-cookbook/