PKI Public Key Infrastructure: Certificados, CA y TLS/SSL
Este artículo ofrece una explicación exhaustiva de la Public Key Infrastructure, incluyendo certificados, autoridades certificadoras e implementación de TLS/SSL.
En resumen
PKI es el marco organizativo y técnico para crear, distribuir, validar y revocar claves públicas mediante certificados. Permite establecer identidades de confianza para personas, máquinas y servicios.
Descripción técnica compacta
Una Public Key Infrastructure (PKI) consiste en una Root CA y Intermediate CAs subordinadas que emiten, firman y revocan certificados X.509 mediante CRL u OCSP.
Componentes principales:
- Certificate Authority (CA): Emite certificados
- Registration Authority (RA): Verifica identidades
- Certificate Repository: Almacena certificados
- Validation Authority: Valida certificados
Contenido de los certificados:
- Public Key: Clave pública del titular
- Identity Information: CN, SAN, OU, O, C
- Validity Period: Período de validez
- Key Usage: Restricción de uso de la clave
- Digital Signature: Firma de la CA emisora
Modelo de confianza:
- Chain of Trust: Estructura jerárquica de CAs
- Root Certificates: Anclas de confianza en truststores
- Certificate Validation: Verificación de la cadena de certificados
PKI soporta autenticación, firma, cifrado y no repudio en TLS, S/MIME, Code Signing y mTLS.
Puntos clave para exámenes
- Jerarquía de Root CA e Intermediate CA
- Formato e contenidos de certificados X.509
- Gestión de Chain of Trust y Truststore
- CRL (Certificate Revocation List) y OCSP (Online Certificate Status Protocol)
- Handshake TLS/SSL con validación de certificados
- Proceso CSR (Certificate Signing Request)
- mTLS (Mutual TLS) para autenticación de cliente
- Relevante para IT-Sicherheit y Netzwerktechnik
Componentes centrales
- Root Certificate Authority: Autoridad de confianza suprema
- Intermediate Certificate Authority: Instancias intermedias para delegación
- End Entity Certificate: Certificado para servidor, cliente o servicios
- Certificate Signing Request: Solicitud para emitir certificados
- Certificate Revocation List: Lista de certificados revocados
- OCSP Responder: Verificación online del estado de certificados
- Truststore: Almacén de certificados raíz de confianza
- Keystore: Almacén de certificados propios y claves privadas
Ejemplos prácticos
Crear un certificado con OpenSSL
# Generar clave privada
openssl genrsa -out server.key 2048
# Crear Certificate Signing Request (CSR)
openssl req -new -key server.key -out server.csr \
-subj "/C=DE/ST=Berlin/L=Berlin/O=IRC-Coding/OU=IT/CN=irc-coding.de"
# Certificado autofirmado (para testing)
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
# Mostrar certificado
openssl x509 -in server.crt -text -noout
# Validar certificado
openssl verify -CAfile ca.crt server.crt
Gestión de Java Keystore
// Crear keystore con KeyTool
// keytool -genkeypair -alias server -keyalg RSA -keysize 2048 \
// -keystore keystore.jks -validity 365
// Exportar CSR
// keytool -certreq -alias server -keystore keystore.jks -file server.csr
// Importar certificado
// keytool -importcert -alias server -file server.crt \
// -keystore keystore.jks -trustcacerts
// Código Java para validación de certificados
import java.security.cert.*;
import java.io.FileInputStream;
public class CertificateValidator {
public static boolean validateCertificate(String certPath, String caPath) {
try {
// Cargar certificado
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate)
cf.generateCertificate(new FileInputStream(certPath));
// Cargar certificado CA
X509Certificate caCert = (X509Certificate)
cf.generateCertificate(new FileInputStream(caPath));
// Validar cadena de certificados
cert.checkValidity(); // Verificar período de validez
cert.verify(caCert.getPublicKey()); // Verificar firma
// Verificación CRL/OCSP (simplificada)
if (isRevoked(cert)) {
return false;
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
private static boolean isRevoked(X509Certificate cert) {
// Implementar verificación CRL u OCSP
return false;
}
}
Servidor TLS con Node.js
const https = require('https');
const fs = require('fs');
// Configuración del servidor TLS
const tlsOptions = {
key: fs.readFileSync('server.key'),
cert: fs.readFileSync('server.crt'),
ca: fs.readFileSync('ca.crt'), // Para autenticación de cliente
requestCert: true, // Requerir mTLS
rejectUnauthorized: true // Rechazar certificados inválidos
};
const server = https.createServer(tlsOptions, (req, res) => {
// Información del certificado del cliente
const clientCert = req.socket.getPeerCertificate();
if (clientCert) {
console.log('Client authenticated:', clientCert.subject.CN);
res.writeHead(200);
res.end('Hello authenticated client!');
} else {
res.writeHead(401);
res.end('Client certificate required');
}
});
server.listen(8443, () => {
console.log('TLS Server listening on port 8443');
});
Cliente TLS en Python con validación de certificados
import ssl
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.ssl_ import create_urllib3_context
class TLSAdapter(HTTPAdapter):
def init_poolmanager(self, *args, **kwargs):
context = create_urllib3_context()
context.check_hostname = True
context.verify_mode = ssl.CERT_REQUIRED
context.load_verify_locations('ca.crt') # Cargar certificado CA
# mTLS con certificado del cliente
context.load_cert_chain('client.crt', 'client.key')
kwargs['ssl_context'] = context
return super().init_poolmanager(*args, **kwargs)
# Cliente TLS con validación de certificados
session = requests.Session()
session.mount('https://', TLSAdapter())
try:
response = session.get('https://secure-api.example.com/data')
print("Response:", response.json())
except requests.exceptions.SSLError as e:
print("TLS Error:", e)
except Exception as e:
print("General Error:", e)
Revocación de certificados (CRL/OCSP)
// Verificación de revocación basada en CRL
import java.security.cert.*;
import java.net.URL;
import java.io.InputStream;
public class CRLValidator {
public static boolean checkRevocation(X509Certificate cert) {
try {
// Extraer Distribution Points de CRL del certificado
String crlUrl = getCRLDistributionPoint(cert);
if (crlUrl != null) {
// Descargar CRL
URL url = new URL(crlUrl);
InputStream in = url.openStream();
// Cargar y validar CRL
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509CRL crl = (X509CRL) cf.generateCRL(in);
// Verificar si el certificado ha sido revocado
return !crl.isRevoked(cert);
}
return true; // No hay CRL disponible
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
private static String getCRLDistributionPoint(X509Certificate cert) {
// Extraer Distribution Point de CRL de las extensiones del certificado
// La implementación requeriría análisis de ASN.1
return null;
}
}
Jerarquía de PKI y cadena de confianza
Estructura típica de PKI
Root CA (autofirmada)
├── Intermediate CA 1 (para servidores web)
│ ├── irc-coding.de
│ └── api.irc-coding.de
├── Intermediate CA 2 (para firma de código)
│ ├── desktop-app.exe
│ └── mobile-app.apk
└── Intermediate CA 3 (para correo electrónico)
├── user1@irc-coding.de
└── user2@irc-coding.de
Cadena de validación de certificados
public class ChainValidator {
public static boolean validateChain(X509Certificate[] chain,
X509Certificate[] trustedCAs) {
try {
// Inicializar Trust Anchors
Set<TrustAnchor> trustAnchors = new HashSet<>();
for (X509Certificate ca : trustedCAs) {
trustAnchors.add(new TrustAnchor(ca, null));
}
// Configurar parámetros PKIX
PKIXParameters params = new PKIXParameters(trustAnchors);
params.setRevocationEnabled(true); // Activar verificación CRL/OCSP
// Certificate Path Builder
CertPathBuilder builder = CertPathBuilder.getInstance("PKIX");
X509CertSelector selector = new X509CertSelector();
selector.setCertificate(chain[0]);
PKIXBuilderParameters builderParams =
new PKIXBuilderParameters(trustAnchors);
builderParams.setRevocationEnabled(true);
// Validar cadena de certificados
CertPathBuilderResult result = builder.build(builderParams);
CertPathValidator validator = CertPathValidator.getInstance("PKIX");
CertPathValidatorResult validatorResult =
validator.validate(result.getCertPath(), params);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
Ventajas y desventajas
Ventajas de PKI
- Seguridad: Base criptográfica robusta
- Escalabilidad: Estructura jerárquica para grandes organizaciones
- Estandarización: X.509 está ampliamente difundido
- Flexibilidad: Múltiples casos de uso (TLS, Code Signing, etc.)
- No repudio: Las firmas digitales demuestran autoría
Desventajas
- Complejidad: Configuración y mantenimiento costosos
- Costos: Las CAs comerciales requieren licencias
- Sobrecarga operativa: Rotación de claves, gestión de certificados
- Punto único de fallo: El fallo de la Root CA afecta toda la PKI
Preguntas frecuentes de examen
-
¿Cuál es la diferencia entre Root CA e Intermediate CA? La Root CA es autofirmada y actúa como ancla de confianza, mientras que la Intermediate CA es firmada por la Root CA y delega la emisión de certificados.
-
Explica la Chain of Trust. Es la validación jerárquica que va desde el certificado final pasando por las Intermediate CAs hasta la Root CA.
-
¿Cuál es el propósito de CRL y OCSP? Verificar si los certificados han sido revocados antes de su fecha de vencimiento (por compromiso, cambio de empleo, etc.).
-
¿Cuándo se utiliza mTLS? Para autenticación mutua entre servidor y cliente en APIs y microservicios.
Fuentes principales
- https://de.wikipedia.org/wiki/Public-Key-Infrastruktur
- https://tools.ietf.org/html/rfc5280
- https://www.ietf.org/rfc/rfc5280.txt



