Al mòdul anterior vam construir la mentalitat: objectius, entropia, Kerckhoffs i les regles d'or. Però el deute central de MediNube segueix obert: els historials de pacients com Ana Pérez continuen sense xifrar en disc. En aquest mòdul comencem a saldar-lo, i ho fem per on comença gairebé tota la criptografia pràctica: el xifratge simètric, el que protegeix la major part de les dades del món — discos, bases de dades, trànsit TLS, missatgeria. En aquesta lliçó coneixeràs els dos protagonistes moderns, AES i ChaCha20, entendràs la diferència entre xifrar en bloc i xifrar en flux, i faràs el primer pas amb la llibreria triada a 01-04: pyca/cryptography. Tancarem amb un primer xifratge real de bytes a MediNube — i amb un avís honest: encara ens falta una peça (els modes d'operació) per fer-ho bé.
Contingut
- Què és el xifratge simètric
- Xifratge en bloc vs xifratge en flux
- AES: l'estàndard mundial
- ChaCha20: el campió del programari
- AES vs ChaCha20: quin triar
- Primer contacte amb pyca/cryptography i la capa
hazmat - Cas MediNube: primer xifratge de bytes amb AES (i per què encara no n'hi ha prou)
Què és el xifratge simètric
El xifratge simètric és l'esquema més antic i intuïtiu: la mateixa clau serveix per xifrar i per desxifrar. Qui té la clau pot fer totes dues coses; qui no la té, cap.
Formalment: desxifrar(K, xifrar(K, missatge)) == missatge. Tres propietats el defineixen:
- Una sola clau secreta. Tota la seguretat es concentra en ella (Kerckhoffs en estat pur: l'algorisme és públic, la clau no).
- És molt ràpid. Els algorismes simètrics moderns xifren a velocitats de gigabytes per segon. Per això són l'eina per a volums de dades: discos sencers, bases de dades, streams de vídeo.
- La clau és curta i de màxima entropia. Per al nostre estàndard del curs, 256 bits = 32 bytes sortits del CSPRNG (
os.urandom(32)), tal com vam fixar a 01-03. No és una contrasenya: és soroll pur.
I el punt feble? Que les dues parts necessiten la mateixa clau, i fer-la-hi arribar de forma segura a través d'una xarxa hostil és un problema gens trivial. Aquest problema — l'intercanvi de claus — té solucions elegants que veurem al mòdul 4 (criptografia asimètrica i Diffie-Hellman). En aquest mòdul l'aparquem deliberadament: el nostre cas d'ús és MediNube xifrant les seves pròpies dades en disc, on "l'altre extrem" som nosaltres mateixos i no hi ha cap clau a transportar.
Xifratge en bloc vs xifratge en flux
Els algorismes simètrics es divideixen en dues famílies segons com processen les dades:
- Un xifratge en bloc (block cipher) transforma blocs de mida fixa. AES treballa amb blocs d'exactament 16 bytes: li dones 16 bytes, et retorna 16 bytes xifrats. És com una màquina troqueladora: peces de mida exacta, una a una.
- Un xifratge en flux (stream cipher) genera a partir de la clau un doll de bytes pseudoaleatoris (el keystream) i el combina amb el missatge mitjançant XOR, byte a byte. Pot xifrar 1 byte o 1 GB sense preocupar-se de mides: és com una mànega.
| Característica | Xifratge en bloc | Xifratge en flux |
|---|---|---|
| Unitat de treball | Bloc fix (AES: 16 bytes) | Byte a byte (keystream XOR missatge) |
| Missatges de qualsevol longitud? | No directament: cal un mode d'operació (lliçó 02-02) i de vegades farciment | Sí, de forma natural |
| Longitud del xifrat | Múltiple del bloc (amb farciment) | Idèntica a la del missatge |
| Exemple modern | AES | ChaCha20 |
| Exemples històrics | DES, 3DES (obsolets) | RC4 (trencat, prohibit a TLS) |
| Risc característic | Usar malament el mode d'operació | Reutilitzar el nonce (catàstrofe, lliçó 02-02) |
Un matís que veurem a la propera lliçó: la frontera és menys rígida del que sembla, perquè certs modes d'operació (com CTR) converteixen un xifratge en bloc en un xifratge en flux. Queda't amb la idea estructural: AES tot sol només sap xifrar 16 bytes exactes; tota la resta ho aporta el mode.
AES: l'estàndard mundial
AES (Advanced Encryption Standard) és el xifratge simètric estàndard del planeta des de 2001, i la seva història és el millor exemple viu del principi de Kerckhoffs que vam estudiar a 01-04 — l'anti-Mifare, l'anti-CSS:
- El 1997, el NIST nord-americà va convocar un concurs públic internacional per substituir l'envellit DES (clau de 56 bits, ja trencable per força bruta).
- Es van presentar 15 candidats d'equips d'arreu del món, amb el disseny completament publicat. Durant tres anys, els millors criptoanalistes del planeta — inclosos els equips rivals — els van atacar públicament.
- El 2000 va guanyar Rijndael, dels belgues Joan Daemen i Vincent Rijmen. El 2001 es va estandarditzar com AES.
Vint-i-cinc anys d'escrutini mundial després, encara no es coneix cap atac pràctic contra AES ben usat. Compara-ho amb el patró de desastre dels algorismes secrets de la lliçó anterior: aquesta asimetria de revisió és exactament el que compra el disseny obert.
Dades tècniques que has de conèixer:
- Bloc fix de 128 bits (16 bytes). Sempre, amb qualsevol mida de clau. Internament, AES organitza aquests 16 bytes en una matriu 4×4 i li aplica diverses rondes de transformacions (substitucions, rotacions de files, barreges de columnes i combinació amb subclaus derivades de la clau principal). No cal que sàpigues implementar-les — regla d'or núm. 1 — però sí entendre'n la conseqüència: cada bloc de 16 bytes es transforma per complet; canviar un sol bit de l'entrada canvia de forma impredictible els 16 bytes de la sortida.
- Tres mides de clau: 128, 192 i 256 bits, amb 10, 12 i 14 rondes respectivament. Les tres són segures avui (2^128 ja és inabastable, com vam calcular a 01-03). En aquest curs fem servir AES-256, l'estàndard que vam fixar: el sobrecost és mínim i dona marge extra a llarg termini.
- Acceleració per maquinari: AES-NI. Des d'aproximadament el 2010, pràcticament totes les CPU de servidor i escriptori (Intel, AMD, i equivalents en ARM) inclouen instruccions natives que executen rondes d'AES directament en silici. Resultat: velocitats de diversos GB/s per nucli i, de regal, resistència als atacs de temps que vam veure a 01-04 (la instrucció triga sempre el mateix). És una de les raons per les quals AES domina en servidors.
ChaCha20: el campió del programari
ChaCha20 és el gran xifratge en flux modern. El va dissenyar Daniel J. Bernstein (djb, una de les figures més influents de la criptografia actual) el 2008, com a evolució del seu Salsa20. A diferència d'AES, no va sortir d'un concurs d'agència, sinó de l'escrutini acadèmic i de la seva adopció per part de la indústria: avui és estàndard de l'IETF i l'utilitzen TLS 1.3, WireGuard, SSH i Android.
Els seus trets distintius:
- Clau de 256 bits, sempre. No hi ha variants menors — encaixa directament amb el nostre estàndard del curs.
- És un xifratge en flux: genera keystream en blocs interns de 64 bytes fent servir només sumes, XOR i rotacions sobre enters de 32 bits — operacions que qualsevol CPU fa de forma nativa i en temps constant. Res de taules de substitució en memòria, que és on els xifratges implementats en programari pur solen filtrar informació per la memòria cau (canal lateral, 01-04).
- Brilla on no hi ha AES-NI: mòbils de gamma baixa, dispositius embeguts/IoT, routers, i qualsevol programari que hagi de córrer ràpid i segur sense dependre del maquinari. Google el va impulsar a TLS precisament per accelerar Android.
- Necessita un nonce (number used once, número usat una sola vegada): un valor públic de 12 bytes (96 bits, en la variant IETF) que ha de ser diferent en cada xifratge amb la mateixa clau. El nonce és la posició inicial de la "mànega" de keystream: si repeteixes la parella clau+nonce, dos missatges es xifren amb el mateix keystream, i això és una catàstrofe que demostrarem amb codi a la propera lliçó. De moment, grava't la regla: nonce = mai repetir amb la mateixa clau.
AES vs ChaCha20: quin triar
| AES-256 | ChaCha20 | |
|---|---|---|
| Tipus | Bloc (16 bytes) | Flux |
| Clau | 128/192/256 bits (curs: 256) | 256 bits |
| Origen | Concurs públic NIST (Rijndael, 1998-2001) | D. J. Bernstein (2008), estàndard IETF |
| Velocitat amb AES-NI | Excel·lent (GB/s per nucli) | Bona |
| Velocitat sense maquinari dedicat | Regular, i amb risc de canal lateral si la implementació usa taules | Excel·lent i en temps constant per disseny |
| On brilla | Servidors i escriptori moderns, compliment normatiu (FIPS) | Mòbil, embegut, programari pur, VPNs (WireGuard) |
| Estat | Estàndard mundial, sense atacs pràctics | Estàndard IETF, sense atacs pràctics |
Criteri pràctic per triar — i avançament important: a la lliçó 02-03 veuràs que en el món real cap dels dos s'usa "a pèl", sinó en les seves construccions autenticades (AES-GCM i ChaCha20-Poly1305), però el criteri d'elecció és el mateix:
- Servidor modern amb AES-NI (el cas de MediNube, que corre al núvol): AES-256. Màxima velocitat, màxima compatibilitat normativa.
- Clients heterogenis, mòbil, embegut, o programari que no controla el seu maquinari: ChaCha20.
- T'equivoques gaire triant "malament"? No: tots dos són segurs. L'elecció és de rendiment i ecosistema, no de seguretat. El que sí que trenca la seguretat és l'ús incorrecte (modes, nonces, integritat) — d'això van les dues properes lliçons.
Per a MediNube fixem doncs: AES-256 com a algorisme del format v1 promès a 01-04.
Primer contacte amb pyca/cryptography i la capa hazmat
A 01-04 vam triar pyca/cryptography com a llibreria del curs. S'instal·la així:
Comprovació ràpida que tot està al seu lloc:
import cryptography print(cryptography.__version__) # p. ex. 45.0.3 — qualsevol versió recent serveix
La llibreria està dividida en dos nivells, i entendre aquesta divisió és entendre'n la filosofia:
- Receptes d'alt nivell (
cryptography.fernet): decisions ja preses per experts — algorisme, mode, integritat, format. Difícils d'usar malament. Les veurem a 02-03. - La capa
hazmat(cryptography.hazmat): les primitives criptogràfiques directes. El nom és literal — hazardous materials, materials perillosos — i és un avís dels propis autors: aquí ningú t'impedeix combinar les peces de forma insegura. Xifrar ambhazmati fer-ho bé exigeix saber exactament què estàs fent; per això existeix aquest mòdul.
Per què aprendrem amb hazmat en lloc de quedar-nos amb les receptes? Perquè la teva feina a MediNube ho exigeix: els formats de dades reals (el v1 que dissenyarem, TLS, JWT, fitxers xifrats de tercers) estan construïts amb aquestes peces, i per revisar codi heretat — el teu dia a dia en aquest curs — necessites reconèixer les peces i els seus paranys. La regla professional queda així: usa la recepta d'alt nivell quan et valgui; baixa a hazmat només sabent què fas — que és exactament el que aquest mòdul t'ensenyarà.
Cas MediNube: primer xifratge de bytes amb AES (i per què encara no n'hi ha prou)
Xifrem els nostres primers bytes de veritat. Per veure AES en estat pur — la troqueladora de blocs, sense res al voltant — li donarem exactament un bloc de 16 bytes: un fragment de l'historial d'Ana Pérez.
import os
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
# 1. La clau: 32 bytes (256 bits) del CSPRNG, com mana la regla d'or núm. 3.
clau = os.urandom(32)
# 2. Exactament UN bloc: 16 bytes. (Dada fictícia, com tot a MediNube.)
bloc = "GRUP SANGUINI:0+".encode("utf-8")
assert len(bloc) == 16
# 3. Construïm el xifrador AES.
# L'API ens OBLIGA a indicar un mode; fem servir ECB, que significa
# "aplica el xifratge en bloc directament, sense res més".
# ⚠️ Només és acceptable perquè xifrem UN únic bloc solt:
# a la propera lliçó veuràs per què ECB és un desastre per a dades reals.
xifrador = Cipher(algorithms.AES(clau), modes.ECB()).encryptor()
xifrat = xifrador.update(bloc) + xifrador.finalize()
print(xifrat.hex()) # 16 bytes d'aspecte aleatori, p. ex. '3ad77bb40d7a3660...'
# 4. Desxifrar: mateixa clau (simètric), operació inversa.
desxifrador = Cipher(algorithms.AES(clau), modes.ECB()).decryptor()
recuperat = desxifrador.update(xifrat) + desxifrador.finalize()
print(recuperat.decode("utf-8")) # GRUP SANGUINI:0+
assert recuperat == blocDesglossament línia a línia:
os.urandom(32)— la clau neix del CSPRNG del sistema (01-03). Mai d'una contrasenya escrita a mà ni derandom. (I com es converteix una contrasenya en una clau quan no hi ha més remei? Aquest és exactament el tema de la lliçó 02-04.)algorithms.AES(clau)— selecciona AES; la mida de la clau (32 bytes) determina automàticament la variant (AES-256).modes.ECB()— el "mode nul": aplicar la primitiva a cada bloc de 16 bytes, tal qual. L'API dehazmatno et deixa ni instanciar unCiphersense declarar un mode: la llibreria t'està dient que un xifratge en bloc sense mode no és un sistema de xifratge complet.encryptor()/update()/finalize()— el patró de treball dehazmat: crees l'operador, li vas passant dades ambupdate()(es pot cridar diverses vegades, útil per a fitxers grans), i tanques ambfinalize().- Tot són bytes, mai
str— la disciplinaencode/decodede 01-02 aplica de principi a fi. - Observa que el xifrat també són 16 bytes indistingibles de soroll: sense la clau, no hi ha res a "llegir" en ells.
Funciona. I tanmateix, això no resol el deute de MediNube, per dues raons que defineixen la resta del mòdul:
- Un historial real no fa 16 bytes. Com es xifren 40 KB amb una màquina que només processa peces de 16 bytes? Aquesta és la feina dels modes d'operació, i triar malament (per exemple, l'ECB que acabem d'usar) filtra informació encara que AES sigui perfecte. És la propera lliçó, 02-02.
- Xifrar no impedeix manipular. Res en aquest esquema detecta que un atacant alteri els bytes xifrats. La solució és el xifratge autenticat (AEAD), lliçó 02-03.
Com sempre a MediNube: dades fictícies, i recorda que un desplegament real amb dades sanitàries exigeix revisió de seguretat i compliance (RGPD) per part de professionals.
Errors Comuns i Consells
- Dir "encriptar". El terme normatiu en català és xifrar (i desxifrar). En aquest curs, sempre.
- Generar la clau amb
randomo derivar-la "a ull" d'un text. La clau simètrica són 32 bytes del CSPRNG:os.urandom(32)osecrets.token_bytes(32). Una contrasenya no és una clau (lliçó 02-04). - Quedar-se en aquest exemple i xifrar dades reals amb ECB. L'exemple d'avui és didàctic i vàlid només per a un bloc solt. A la propera lliçó veuràs amb els teus propis ulls què filtra ECB amb dades reals.
- Creure que AES-256 "és més segur" que ChaCha20 (o viceversa). Tots dos són segurs; l'elecció és de plataforma i rendiment. La inseguretat gairebé sempre ve de l'ús, no de l'algorisme.
- Oblidar que la mateixa clau desxifra. És la definició de simètric: qualsevol que obtingui la clau ho llegeix tot. On i com guardar aquesta clau és un tema seriós que abordarem al mòdul 6; mentrestant, mai al codi font ni al repositori.
- Confondre el nonce amb un secret. El nonce de ChaCha20 (i els IV que vindran a la propera lliçó) són públics; la seva única obligació és no repetir-se amb la mateixa clau.
Exercicis
-
Classifica. Per a cada escenari de MediNube, raona si encaixa millor AES-256 o ChaCha20: (a) xifrar els historials als servidors cloud de MediNube (CPU Intel modernes); (b) una futura app mòbil per a pacients que xifri notes localment, incloent-hi terminals Android antics; (c) un dispositiu IoT de telemetria mèdica amb un microcontrolador ARM sense acceleració criptogràfica.
-
La troqueladora. Modifica l'exemple de la lliçó per intentar xifrar
"HISTORIAL D'ANA PEREZ"(21 bytes) amb AES en mode ECB. Què passa i per què? Què et diu l'error sobre el que falta per aprendre? -
Anada i tornada amb la clau equivocada. Partint de l'exemple de la lliçó, desxifra el bloc amb una clau diferent (un altre
os.urandom(32)). Dona error o retorna alguna cosa? Què retorna, i què et diu això sobre si el xifratge "sap" quan la clau és correcta?
Solucions
-
(a) AES-256: servidors moderns amb AES-NI, màxim rendiment — és l'elecció que fixem per al format
v1de MediNube. (b) ChaCha20: parc de dispositius heterogeni on molts no tenen acceleració AES; en programari pur ChaCha20 és més ràpid i en temps constant per disseny. (c) ChaCha20: és el cas arquetípic — CPU modesta, sense maquinari criptogràfic, i només sumes/XOR/rotacions que qualsevol ARM executa bé. -
xifrador.finalize()llançaValueError: The length of the provided data is not a multiple of the block length.AES només processa blocs exactes de 16 bytes; 21 bytes no hi encaixen. Falta el que aporta un mode d'operació complet: trossejar, encadenar i, quan toca, farcir (padding) l'últim bloc — exactament el temari de la lliçó 02-02. -
No dona error: retorna 16 bytes d'escombraries pseudoaleatòries (que a més probablement ni tan sols es puguin decodificar com a UTF-8). El xifratge en bloc "a pèl" no inclou cap verificació: desxifrar amb qualsevol clau sempre "funciona" mecànicament i produeix alguna cosa. Detectar que el resultat és vàlid — i que ningú ha manipulat les dades — requereix autenticació, que és justament el que afegeix el xifratge autenticat de la lliçó 02-03.
Conclusió
Ja tens els dos protagonistes del xifratge simètric modern i el seu repartiment de papers: AES-256 (xifratge en bloc de 16 bytes, nascut d'un concurs públic que és Kerckhoffs en acció, imbatible sobre maquinari amb AES-NI) i ChaCha20 (xifratge en flux de Bernstein, clau de 256 bits, nonce irrepetible, el rei del programari pur i el mòbil). Saps que l'elecció entre tots dos és de plataforma, no de seguretat, i has escrit el teu primer xifratge real amb pyca/cryptography, coneixent la frontera entre les receptes d'alt nivell i la capa hazmat — materials perillosos que aquest mòdul t'ensenya a manejar. Però l'exemple final va deixar dos caps solts enormes: AES sol, a pèl, ni xifra missatges de mida real ni detecta manipulacions. El primer cap el lliguem ja a la propera lliçó, 02-02: Modes d'Operació — on veuràs, amb una demostració en Python sobre un historial de MediNube, per què el mode ECB que avui usem "de joguina" és una filtració de dades esperant a passar, i què fan bé CBC i CTR. Ens veiem allà.
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
