Ja saps què és un certificat (05-01) i com TLS el posa a treballar a cada connexió (05-02). Però en producció el certificat no és un concepte: és un artefacte operatiu amb data de caducitat, que algú ha d'emetre, desplegar, vigilar, renovar i —el dia dolent— revocar. La majoria dels incidents "de TLS" del món real no són criptoanàlisi: són certificats que van caducar un diumenge perquè ningú els va renovar. En aquesta lliçó tanques el mòdul amb la part que converteix tot l'anterior en un servei fiable: el cicle de vida complet, l'automatització amb ACME/Let's Encrypt i certbot, els mecanismes de revocació i les seves misèries (CRL, OCSP, stapling), un monitor de caducitats en Python per als dominis de MediNube, el cicle de vida dels certificats interns i de client mTLS de les clíniques, i un simulacre d'incident: la clau privada de portal.medinube.example filtrada en un repositori públic, amb el seu runbook pas a pas.
Contingut
- El certificat com a artefacte operatiu: el cicle de vida
- Caducitat: per què les vides curtes són un avantatge
- ACME i Let's Encrypt: emissió i renovació automàtiques
- certbot per a portal.medinube.example
- Revocació: quan i com (CRL, OCSP, stapling)
- Monitorització: assabentar-se abans de caducar
- Certificats interns: la mini-PKI i els clients mTLS de les clíniques
- Pinning: menció i riscos
- Incident simulat: clau privada filtrada — el runbook
El certificat com a artefacte operatiu: el cicle de vida
Un certificat neix, treballa i mor. Tot el que farem en aquesta lliçó encaixa en aquest cicle:
flowchart LR
E["Emetre<br/>(CSR → la CA signa)"] --> D["Desplegar<br/>(nginx, recarrega)"]
D --> M["Monitoritzar<br/>(caduca aviat?<br/>continua desplegat el bo?)"]
M -->|"arriba la finestra<br/>de renovacio"| R["Renovar<br/>(nova CSR, nou cert,<br/>idealment nova clau)"]
R --> D
M -->|"compromis de clau<br/>o baixa de l'entitat"| X["Revocar<br/>(CRL/OCSP + reemetre)"]
X --> E
Llegeix el diagrama com un bucle: la vida normal és emetre → desplegar → monitoritzar → renovar → desplegar..., i la revocació és la sortida d'emergència. Cada fletxa és un punt de fallada clàssic: emetre i no desplegar (el certificat nou es queda en una carpeta), desplegar i no recarregar nginx (serveix el vell fins que es reinicia), renovar sense monitoritzar (no saps si ha funcionat), revocar sense reemetre (servei caigut). La tesi de la lliçó: tot el que pugui ser automàtic, ho ha de ser, i el que no, necessita un runbook escrit.
Caducitat: per què les vides curtes són un avantatge
Pot semblar un fàstic que els certificats caduquin, i cada vegada abans: dels 3-5 anys de la dècada de 2010 es va passar al màxim de 398 dies acceptat pels navegadors (2020), Let's Encrypt emet a 90 dies, i la indústria (CA/Browser Forum) té aprovat el descens esglaonat cap a certificats d'uns 47 dies en els propers anys. No és sadisme, és seguretat:
- Limita la finestra de dany. Si una clau es compromet i ningú ho detecta, un certificat de 90 dies deixa de valer només en setmanes; un de 3 anys, en anys. Com veuràs més avall, la revocació funciona malament: la vida curta és la revocació que sí que funciona.
- Força l'automatització. Ningú renova a mà cada 90 dies sense fallar; amb vides curtes, o automatitzes o pateixes. I un procés automatitzat i exercitat cada 60 dies és un procés que saps que funciona — comparat amb el ritual anual que ningú recorda com es feia.
- Accelera la criptoagilitat (regla núm. 8). Si demà cal abandonar un algorisme o canviar de CA, un parc de certificats que rota cada 90 dies es migra sencer en setmanes.
- Manté les dades fresques. Dominis que canvien de propietari, empreses que desapareixen: la informació validada per la CA caduca aviat.
Canvi de mentalitat per a l'equip de MediNube: el certificat no és "una cosa que s'instal·la", és una cosa que rota, com haurien de rotar les claus (tema que el mòdul 6 retoma per a les claus d'aplicació).
ACME i Let's Encrypt: emissió i renovació automàtiques
Let's Encrypt (2015) va canviar el joc: certificats DV gratuïts, emesos en segons, mitjançant un protocol obert d'emissió automatitzada: ACME (RFC 8555). La idea d'ACME és automatitzar just el que a 05-01 feia "la CA per darrere": verificar que qui demana el certificat controla el domini. Per fer-ho proposa reptes (challenges):
| HTTP-01 | DNS-01 | |
|---|---|---|
| Què exigeix demostrar | Control del servidor web del domini | Control del DNS del domini |
| Mecànica | La CA demana http://el-teu-domini/.well-known/acme-challenge/<token> i hi ha de trobar el valor acordat |
Publiques un registre TXT _acme-challenge.el-teu-domini amb el valor acordat |
| Requisits | Port 80 accessible des d'Internet | API del teu proveïdor DNS (per automatitzar) |
Wildcard (*.medinube.example)? |
No | Sí — és l'única via |
| Serveix per a màquines no exposades a Internet? | No | Sí (el repte es resol al DNS, no a la màquina) |
| Complexitat | Mínima | Depèn del proveïdor DNS |
El flux complet, amb les peces que ja coneixes: el client ACME genera una clau de compte (signatures, 04-03) → demana un certificat per a portal.medinube.example → la CA proposa el repte → el client el resol (fitxer HTTP o TXT al DNS) → la CA ho comprova des de fora → el client envia la CSR (05-01) → la CA emet i publica als logs de Certificate Transparency (05-01) → el client instal·la el certificat. Zero humans.
certbot per a portal.medinube.example
certbot és el client ACME de referència. Posada en marxa per al portal, amb el nginx de 05-02 ja servint el domini:
# Instal·lació a Debian/Ubuntu (existeix també via snap/pip):
sudo apt install certbot python3-certbot-nginx
# Emissió + configuració automàtica de nginx en un sol pas:
# --nginx: fa servir nginx per resoldre el repte HTTP-01 I edita la config
# (rutes ssl_certificate*, redirecció 80→443 si es demana).
# -d: el domini (repetible: -d www.medinube.example ...).
sudo certbot --nginx -d portal.medinube.example \
--email [email protected] --agree-tosDesprés d'això, certbot deixa el material a rutes estables que nginx referencia (fixa't: són les de 05-02!):
/etc/letsencrypt/live/portal.medinube.example/fullchain.pem— fulla + intermèdia./etc/letsencrypt/live/portal.medinube.example/privkey.pem— la clau privada (permisos restrictius;live/són enllaços simbòlics a l'última versió, per això nginx no necessita canvis en renovar).
La renovació automàtica és la meitat important. Els paquets moderns instal·len un timer de systemd (o un cron) que executa certbot renew dues vegades al dia; certbot només renova els certificats als quals els queden menys de 30 dies, i després de renovar recarrega nginx (via hook):
# Està actiu el timer? systemctl list-timers | grep certbot # Assaig general SENSE emetre res de veritat: verifica repte, permisos i hooks. # Fes-ho SEMPRE després de canviar la configuració de nginx o del DNS. sudo certbot renew --dry-run # Equivalent cron si no hi ha systemd (a les 03:17 i 15:17, minut aleatori # triat per no colpejar la CA a l'hora en punt): # 17 3,15 * * * root certbot renew --quiet --deploy-hook "systemctl reload nginx"
Per al comodí *.medinube.example (si MediNube donés un subdomini a cada clínica) el repte ha de ser DNS-01, amb un plugin del proveïdor DNS (certbot-dns-cloudflare, certbot-dns-route53, etc.) i les seves credencials — credencials que són un secret més a protegir, anticipació directa de 06-01.
Amb això, la "monitorització" no desapareix: la renovació automàtica també falla (ha canviat el DNS, un tallafoc nou bloqueja el port 80, ha caducat la credencial del plugin DNS). Automatitza la renovació i vigila el resultat (secció de monitorització).
Revocació: quan i com (CRL, OCSP, stapling)
Revocar = declarar invàlid un certificat abans de la seva caducitat. Els dos detonants que importen a MediNube:
- Compromís de clau privada (l'incident del final de la lliçó): qualsevol amb la clau pot suplantar el portal fins que el certificat deixi de valer.
- Baixa d'una entitat: el Centre Mèdic Luna rescindeix el seu contracte — el seu certificat de client mTLS (05-02) ha de deixar de donar accés a l'API avui, no quan caduqui.
El problema: avisar tots els clients del món que un certificat concret ja no val és intrínsecament difícil. Els mecanismes, tots imperfectes:
| Mecanisme | Com funciona | Problemes |
|---|---|---|
| CRL (Certificate Revocation List) | La CA publica una llista signada de números de sèrie revocats; el client la descarrega i la consulta | Llistes grans, es cachegen hores/dies; finestra d'exposició; molts clients ni la miren |
| OCSP | El client pregunta a la CA en temps real per aquell certificat | Latència extra; la CA veu la teva navegació (privadesa); i si l'OCSP no respon, gairebé tots els clients fan soft-fail: continuen endavant — un MITM que bloquegi l'OCSP anul·la el mecanisme |
| OCSP stapling | El servidor obté periòdicament una resposta OCSP signada i fresca i la "grapa" al handshake | Arregla latència i privadesa; però si el servidor no grapa, el client sol tolerar-ho (excepte Must-Staple, poc usat); Let's Encrypt de fet va retirar el seu servei OCSP el 2025 per tornar a CRL |
| Vida curta | No revocar: deixar que caduqui en dies/setmanes | És la revocació de facto de l'ecosistema: no depèn que el client comprovi res; la seva "finestra" és la vida restant del certificat |
Lectura honesta de la taula: la revocació a la Web PKI pública és un mecanisme de millor esforç. Per això la indústria empeny vides cada vegada més curtes i per això, després d'un compromís, el runbook (última secció) mai no es queda en "revocar": sempre és revocar + reemetre amb clau nova + desplegar, assumint que hi haurà clients que no s'assabentaran de la revocació. En canvi, en una PKI interna (la nostra mini-PKI), tu controles els dos extrems: pots distribuir CRL de veritat i fer que els teus servidors les apliquin estrictament — la revocació interna sí que pot ser fiable.
Amb la mini-PKI del laboratori, revocar requereix portar una petita base de dades d'emissions (openssl ca en lloc de l'openssl x509 -req directe de 05-01); el flux conceptual és: marcar el sèrial com revocat → regenerar la CRL signada (openssl ca -gencrl) → distribuir-la als servidors que validen (el nginx de mTLS la carrega amb ssl_crl).
Monitorització: assabentar-se abans de caducar
Regla d'operació: cap certificat de MediNube caduca per sorpresa. El monitor més senzill i robust no mira la configuració, mira el que de debò s'està servint — igual que faria un client. Script medinube/monitor_certs.py:
"""Monitor de caducitat de certificats de MediNube.
Es connecta a cada domini com ho faria un client TLS real,
llegeix el certificat presentat i avisa si caduca en < LLINDAR_DIES.
Pensat per a cron diari; l'avís es pot lliurar pel webhook
signat amb HMAC de la lliçó 03-02.
"""
import socket
import ssl
import sys
from datetime import datetime, timezone
from cryptography import x509
# Tot endpoint TLS de MediNube exposat o intern important:
DOMINIS = [
("portal.medinube.example", 443),
("api.medinube.example", 443),
]
LLINDAR_DIES = 30 # marge per reaccionar; > finestra de renovació de certbot
def dies_restants(host: str, port: int) -> int:
"""Retorna els dies de validesa que li queden al certificat servit."""
context = ssl.create_default_context() # validació completa (05-02)
with socket.create_connection((host, port), timeout=10) as tcp:
with context.wrap_socket(tcp, server_hostname=host) as tls:
# getpeercert(binary_form=True) → DER; ho parsem amb
# cryptography per treballar amb objectes, com a 05-01.
der = tls.getpeercert(binary_form=True)
cert = x509.load_der_x509_certificate(der)
restant = cert.not_valid_after_utc - datetime.now(timezone.utc)
return restant.days
def main() -> int:
codi_sortida = 0
for host, port in DOMINIS:
try:
dies = dies_restants(host, port)
except ssl.SSLCertVerificationError as e:
# Un cert invàlid JA (caducat, cadena trencada) és alerta màxima:
print(f"[CRITIC] {host}: el certificat NO és vàlid: {e}")
codi_sortida = 2
continue
except OSError as e:
print(f"[ERROR] {host}: no s'ha pogut connectar: {e}")
codi_sortida = max(codi_sortida, 1)
continue
if dies < LLINDAR_DIES:
print(f"[AVIS] {host}: caduca en {dies} dies (< {LLINDAR_DIES})")
codi_sortida = max(codi_sortida, 1)
else:
print(f"[OK] {host}: {dies} dies restants")
return codi_sortida
if __name__ == "__main__":
sys.exit(main())Punts de disseny, en detall:
- Fem servir
ssl.create_default_context()amb validació: si el certificat ja no és vàlid, volem l'alerta crítica, no llegir-lo igualment. (Per inspeccionar certificats ja caducats caldrien trucs sense validació; per a monitoritzar, la validació és part del test.) getpeercert(binary_form=True)retorna el DER de la fulla;cryptographyens donanot_valid_after_utccom a datetime amb zona, i restem contradatetime.now(timezone.utc)— el mateix patró de l'exercici 2 de 05-01.- El llindar de 30 dies no és casual: certbot renova quan falten <30 dies, així que "queden <30 dies i encara no s'ha renovat" vol dir que l'automatització està fallant i encara hi ha marge humà.
- El codi de sortida (0/1/2) l'entén qualsevol programador de tasques i sistemes de monitorització. En cron:
0 8 * * * python3 /opt/medinube/monitor_certs.py || curl ... # notificar. Per notificar el canal de l'equip, reutilitza el webhook signat de 03-02: l'avís viatja ambX-MediNube-TimestampiX-MediNube-Firma: v1=<hex>, perquè una alerta de seguretat falsificable seria irònica. - Extensió natural (exercici 1): vigilar també els certificats de client mTLS de les clíniques, que no es poden consultar connectant-s'hi, sinó llegint els fitxers PEM emesos per la CA interna.
Certificats interns: la mini-PKI i els clients mTLS de les clíniques
Tot el cicle de vida s'aplica igual —amb matisos— als certificats que no vénen d'una CA pública:
La CA arrel del laboratori (05-01). També caduca (l'hem emesa a 5 anys). La seva renovació és un esdeveniment major: cal redistribuir la nova arrel a tots els clients que hi confien (verify=/etc/medinube/pki/ca.crt a les integracions de 05-02) abans que caduqui la vella, amb un període de solapament en què totes dues són vàlides. Apunta-ho al calendari de l'equip el dia que la creïs: "renovar arrel interna: començar 6 mesos abans de 2031". Les fulles internes, en canvi, es roten com les públiques: curtes i automatitzades (existeixen eines tipus ACME intern — step-ca, HashiCorp Vault — quan la mini-PKI artesanal es queda petita; només la menció, la gestió de secrets és 06-01).
Alta d'una clínica (mTLS, 05-02). Procediment estàndard: la clínica genera la seva clau i la seva CSR (la clau privada mai no viatja, 05-01) amb SAN clinica-sol.clientes.medinube.example → MediNube verifica per canal fiable que la CSR és de qui diu (la validació d'identitat és la feina de la CA, encara que la CA siguis tu!) → la CA interna signa amb vida curta (90 dies) → la clínica instal·la i prova contra l'endpoint mTLS.
Baixa d'una clínica = revocació + defensa en profunditat. El Centre Mèdic Luna causa baixa. Passos: (1) revocar el seu certificat a la CA interna i regenerar/distribuir la CRL al nginx de mTLS; (2) a més, desactivar la seva identitat ($ssl_client_s_dn) a la capa d'autorització de l'aplicació — perquè la regla núm. 9 continua vigent: la criptografia no substitueix el control d'accés, i així la baixa és efectiva encara que una CRL trigui a propagar-se; (3) la vida curta de 90 dies actua de xarxa de seguretat final. Tres capes, cap suficient per si sola, totes tres juntes robustes.
Pinning: menció i riscos
Sentiràs parlar de pinning: fixar al client (típicament una app mòbil) l'empremta del certificat o de la clau pública del servidor, i rebutjar qualsevol altra encara que la cadena sigui vàlida. Puja el llistó contra CA compromeses... i és una trampa operativa: el pin viu a l'app instal·lada, i el certificat rota cada 90 dies. Si rotes la clau sense actualitzar el pin (o sense haver "pinejat" també una clau de recanvi), la teva pròpia app es nega a parlar amb tu — una autodenegació de servei a tota la base instal·lada. L'HPKP dels navegadors es va retirar per aquesta mena d'accidents; avui l'ecosistema prefereix Certificate Transparency (05-01) com a control. Per a MediNube: res de pinning llevat de cas molt justificat, i sempre amb claus de recanvi i caducitat del pin. Sapigueu que existeix, sapigueu per què gairebé mai no compensa.
Incident simulat: clau privada filtrada — el runbook
Divendres, 17:40. Un desenvolupador de MediNube avisa: en fer públic un repositori d'utilitats ha descobert que conté, des de fa tres setmanes, un directori deploy/ amb privkey.pem de portal.medinube.example. La clau privada del certificat del portal és en un repositori públic. Pànic? No: runbook. (Nota prèvia tranquil·litzadora que devem a 05-02: gràcies al forward secrecy de TLS 1.3, el trànsit passat capturat NO és desxifrable amb aquesta clau; el risc és de suplantació a partir d'ara.)
-
Confirmar i acotar (minut 0). És realment la clau en ús? Compara la clau pública derivada del fitxer filtrat amb la del certificat servit — mateixa clau = mateix mòdul/punt públic:
openssl pkey -in privkey_filtrada.pem -pubout | openssl sha256 openssl s_client -connect portal.medinube.example:443 \\ -servername portal.medinube.example </dev/null 2>/dev/null \\ | openssl x509 -noout -pubkey | openssl sha256 # Coincideixen els hashos? Llavors la clau activa està compromesa. -
Tractar la clau com a compromesa des d'ara. Tres setmanes pública = copiada. Retirar-la del repositori no desfà res (l'historial de git i els clons d'altri existeixen); reescriure l'historial és higiene, no remei.
-
Generar clau nova + CSR + reemissió (minuts 5-15). Mai reemetis amb la mateixa clau. Amb certbot és un sol pas que força una clau nova i reemet:
sudo certbot certonly --nginx -d portal.medinube.example --force-renewal # (certbot genera nova privkey per defecte a cada emissió) -
Desplegar i recarregar (minuts 15-20).
sudo systemctl reload nginxi verificar amb l'ordre del pas 1 que el portal ja serveix la clau nova (els hashos ja no coincideixen amb la filtrada) i ambs_clientqueVerify return code: 0 (ok). -
Revocar el certificat vell (minuts 20-30). Ara que el nou ja serveix, invalida l'antic — certbot permet declarar el motiu:
sudo certbot revoke \\ --cert-path /etc/letsencrypt/archive/portal.medinube.example/cert1.pem \\ --reason keycompromiseRecorda la secció de revocació: hi haurà clients que no se n'assabentaran; per això els passos 3-4 van abans — el servei ja està a resguard encara que la revocació es propagui lenta. (Amb Certificate Transparency, a més, vigila que no apareguin emissions noves no sol·licitades per als teus dominis: si l'atacant ha intentat alguna cosa més, es veurà.)
-
Caça col·lateral. Què més hi havia en aquell repositori? Altres claus, tokens, credencials del plugin DNS de certbot? Cada troballa obre el seu propi mini-runbook de rotació.
-
Post-mortem sense culpables (la setmana següent). Causa arrel: una clau privada vivia en un directori de treball normal, a punt de ser commitejada. Accions: escàner de secrets a CI (que bloquegi el push),
.gitignoredefensius, i la de fons: les claus no viuen en repositoris ni en directoris de projecte; viuen en un gestor de secrets. Que és, exactament, on comença el mòdul 6.
Assaja aquest runbook al laboratori (exercici 3) abans de necessitar-lo: un runbook no assajat és una hipòtesi.
Errors Comuns i Consells
- Confiar que "certbot ja està posat" sense vigilar-lo. La renovació automàtica falla en silenci (tallafoc nou, DNS canviat, credencial caducada).
certbot renew --dry-rundesprés de cada canvi d'infraestructura + monitor extern de caducitat. Automatitza i verifica. - Renovar el certificat i no recarregar el servei. nginx carrega el certificat en arrencar/recarregar; si el hook de recàrrega falta, servirà el vell fins que caduqui a la cara dels usuaris. El monitor ho detecta perquè mira el que és servit, no el que és emès.
- Reemetre després d'un compromís reutilitzant la clau privada. Reemetre amb la mateixa clau compromesa és canviar la funda del mòbil robat. Clau nova sempre.
- Confiar la baixa d'una clínica només a la revocació. CRL/OCSP propaguen lent o no es consulten. Baixa = revocar i desautoritzar a l'aplicació i deixar que la vida curta ho rematin.
- Wildcard "per simplificar" sense pensar-hi.
*.medinube.exampleés una sola clau que, compromesa, cobreix tots els subdominis, i exigeix exposar credencials DNS a l'automatisme. Fes-lo servir quan el cas ho demani, no per mandra d'afegir-d. - Oblidar els certificats interns a l'inventari. L'arrel del laboratori, els certs de clínica, el
farmacias-ca.crt... també caduquen. Tot certificat que existeixi ha d'estar a la llista d'algun monitor, o caducarà un diumenge. - Dades sanitàries de per mig: recorda que MediNube és un univers fictici; en un desplegament real, un incident com el del runbook implicaria a més obligacions RGPD (avaluació de la bretxa i, si escau, notificació a l'autoritat) i revisió de compliance — el post-mortem tècnic no és el final del paperam.
Exercicis
Exercici 1 — Monitor de fitxers PEM. Amplia el monitor amb dies_restants_pem(ruta: str) -> tuple[str, int] que, donat un PEM local (p. ex. el certificat de client mTLS de la Clínica Sol emès per la CA interna), retorni (nom_del_subject, dies_restants). Afegeix una llista FITXERS_PEM al main() amb el mateix llindar. Així el monitor cobreix també el que no es pot consultar connectant-s'hi.
Exercici 2 — Decisió de repte ACME. Per a cada cas de MediNube, decideix HTTP-01 o DNS-01 i justifica-ho: (a) portal.medinube.example, servidor web públic; (b) *.clientes.medinube.example, un subdomini per clínica; (c) intranet.medinube.example, resoluble públicament al DNS però només accessible des de la VPN corporativa.
Exercici 3 — Simulacre de compromís al laboratori. Amb la mini-PKI de 05-01: (1) genera una clau i certificat nous per a portal.medinube.example (portal2.key/portal2.crt) signats per la teva CA; (2) verifica amb openssl que la clau pública de portal2.crt és diferent de la de portal.crt (l'equivalent del pas 1 del runbook); (3) apunta quin pas del runbook real no pots reproduir al laboratori tal com l'has muntat, i per què.
Solucions
Solució 1.
def dies_restants_pem(ruta: str) -> tuple[str, int]:
with open(ruta, "rb") as f:
cert = x509.load_pem_x509_certificate(f.read())
restant = cert.not_valid_after_utc - datetime.now(timezone.utc)
return cert.subject.rfc4514_string(), restant.days
FITXERS_PEM = [
"/etc/medinube/pki/ca.crt", # l'arrel també caduca!
"/etc/medinube/pki/clientes/clinica-sol.crt",
]
# A main(), després del bucle de DOMINIS:
for ruta in FITXERS_PEM:
try:
subject, dies = dies_restants_pem(ruta)
except (OSError, ValueError) as e:
print(f"[ERROR] {ruta}: no s'ha pogut llegir/parsejar: {e}")
codi_sortida = max(codi_sortida, 1)
continue
if dies < LLINDAR_DIES:
print(f"[AVIS] {subject} ({ruta}): caduca en {dies} dies")
codi_sortida = max(codi_sortida, 1)
else:
print(f"[OK] {subject}: {dies} dies restants")Nota: per a la CA arrel convé un llindar més gran (p. ex. 180 dies), perquè la seva renovació implica redistribuir confiança a tots els clients, no un simple reload — pots parametritzar el llindar per fitxer com a millora.
Solució 2. (a) HTTP-01: servidor públic amb el 80 accessible, el cas ideal, zero credencials extra. (b) DNS-01 obligatori: és un wildcard, i HTTP-01 no els pot emetre; a més exigeix automatitzar contra l'API del DNS i protegir aquesta credencial (06-01). (c) DNS-01: la CA no pot arribar al servidor per HTTP (només VPN), però el repte DNS es resol al DNS públic sense exposar la intranet. Alternativa raonable que podries haver proposat: emetre'l amb la CA interna del laboratori, ja que només el consumeixen clients corporatius que ja hi confien.
Solució 3.
cd ~/medinube-lab/pki
# (1) clau i certificat nous, mateixa identitat:
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out portal2.key
openssl req -new -key portal2.key \
-subj "/CN=portal.medinube.example/O=MediNube SL" \
-addext "subjectAltName=DNS:portal.medinube.example" -out portal2.csr
openssl x509 -req -in portal2.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-days 90 -sha256 -copy_extensions copy -out portal2.crt
# (2) comparar claus públiques per hash (han de DIFERIR):
openssl x509 -in portal.crt -noout -pubkey | openssl sha256
openssl x509 -in portal2.crt -noout -pubkey | openssl sha256(3) El pas irreproduïble és la revocació efectiva: hem emès amb openssl x509 -req directe, sense la base de dades d'emissions d'openssl ca, així que no hi ha d'on generar una CRL; i encara que n'hi hagués, cap client encara la consulta. És una il·lustració perfecta de la lliçó: revocar només serveix si existeix infraestructura de revocació i els clients l'apliquen — altrament, les teves úniques defenses reals són reemetre+desplegar ràpid i la vida curta del certificat.
Conclusió
Amb aquesta lliçó, el certificat deixa de ser un concepte i passa a ser un artefacte amb vida: emetre → desplegar → monitoritzar → renovar → revocar, amb ACME/certbot automatitzant el bucle feliç per a portal.medinube.example, vides curtes com la revocació que de debò funciona, CRL/OCSP/stapling com a recordatori que avisar tot el món és difícil, un monitor en Python que promet que res caduca per sorpresa (avisant pel webhook signat de 03-02), el cicle complet dels certificats interns i de client mTLS (amb la baixa d'una clínica resolta en tres capes), i un runbook de compromís de clau assajat abans de necessitar-lo.
I amb ella es tanca el Mòdul 5 sencer. Fes balanç del deute que arrossegàvem des de 04-01: "saber de qui és cada clau pública, amb suport verificable". Resolta, i per triplicat: els certificats X.509 i les CA (05-01) lliguen clau i identitat amb signatures que MalloryClinic no pot falsificar; TLS (05-02) posa aquesta confiança a treballar a cada connexió, muntant totes les primitives del curs en un handshake; i l'operació del cicle de vida (aquesta lliçó) garanteix que aquesta confiança no es podreixi amb el temps. L'esquerda està tancada: xifres, signes, verifiques, acordes claus i saps amb qui.
Llavors, hem acabat? Gairebé: queda portar-ho tot al dia a dia del desenvolupament, que és on la criptografia impecable s'espatlla per detalls mundans. L'incident d'aquesta lliçó ho ha insinuat: la clau no va caure per matemàtiques, va caure per un git push. El Mòdul 6: Criptografia en el Desenvolupament Real comença exactament allà — gestió de claus i secrets (06-01: on haurien d'haver viscut aquell privkey.pem i les credencials DNS de certbot), i continua amb el xifratge en repòs i en trànsit aplicat a l'arquitectura de MediNube (06-02, inclòs l'envelope encryption que vam anticipar a 04-05), els tokens signats i JWT per a les sessions del portal (06-03), la galeria d'errors criptogràfics habituals amb tots els _MALAMENT del curs reunits (06-04) i la mirada al que ve: criptografia post-quàntica (06-05). Ja tens totes les peces i tota la confiança; ara toca fer-les servir bé quan ningú no mira. Ens veiem al mòdul 6.
Curs de Criptografia Aplicada
Mòdul 1: Fonaments de la Criptografia
- Què és la criptografia i per a què serveix
- Codificació, ofuscació i xifratge
- Aleatorietat i entropia
- El principi de Kerckhoffs i les regles d'or
Mòdul 2: Criptografia Simètrica
- Xifratge simètric: AES i ChaCha20
- Modes d'operació
- Xifratge autenticat (AEAD)
- Derivació de claus (KDF)
Mòdul 3: Hashes, MAC i Contrasenyes
- Funcions hash criptogràfiques
- Autenticació de missatges amb HMAC
- Emmagatzematge segur de contrasenyes
Mòdul 4: Criptografia Asimètrica
- Fonaments de clau pública i RSA
- Criptografia de corba el·líptica
- Signatures digitals
- Intercanvi de claus: Diffie-Hellman
- Xifratge híbrid
Mòdul 5: PKI, Certificats i TLS
- Certificats X.509 i autoritats de certificació
- TLS a la pràctica
- Gestió del cicle de vida dels certificats
