Al final del mòdul anterior va quedar al descobert l'esquerda que travessa tot el que hem construït fins ara: AES-GCM, HMAC, fins i tot el pepper d'Argon2 — tot pressuposa que les dues parts ja comparteixen una clau secreta. Portem des de 02-01 aparcant la pregunta de com va arribar aquesta clau a tots dos costats. Aquesta lliçó fa el salt conceptual més gran del curs: la criptografia asimètrica, on les claus ja no són un secret compartit sinó un parell — una meitat es guarda sota clau i l'altra es publica als quatre vents. Veuràs la intuïció matemàtica que ho fa possible (funcions d'un sol sentit amb porta falsa), construiràs un RSA de joguina amb enters petits per entendre què passa per dins, i després ho faràs bé amb pyca/cryptography: claus de 3072 bits, farciment OAEP i serialització PEM. En acabar, la Clínica Sol podrà enviar un missatge xifrat a MediNube sense haver acordat cap clau abans — i descobriràs que això obre dues portes noves i deixa una pregunta incòmoda sense resposta.
Contingut
- El canvi de paradigma: un parell de claus
- Funcions d'un sol sentit amb porta falsa
- RSA de joguina: les matemàtiques en petit
- RSA real amb pyca/cryptography
- Per què l'RSA "de llibre de text" és insegur: farciment OAEP
- Els límits fonamentals de l'RSA: mida i velocitat
- Serialització de claus: el format PEM
- La pregunta incòmoda: de qui és aquesta clau pública?
El canvi de paradigma: un parell de claus
Tota la criptografia dels mòduls 2 i 3 és simètrica: la mateixa clau xifra i desxifra, la mateixa clau genera i verifica el MAC. Això obliga que emissor i receptor comparteixin un secret, i compartir secrets per una xarxa on qualsevol escolta és justament el problema que no sabem resoldre.
El 1976, Diffie i Hellman van proposar trencar la simetria: que cada participant tingui dues claus lligades matemàticament:
- La clau privada: es genera localment, mai surt de la màquina del seu propietari. És l'únic secret.
- La clau pública: es deriva de la privada i es pot publicar a qualsevol lloc — una web, un correu, un repositori. Que un atacant la tingui no és cap problema: està dissenyada per ser pública.
La màgia és a la relació entre totes dues: el que fa una, només l'altra ho desfà. D'aquí surten les dues operacions fonamentals de la criptografia asimètrica:
| Operació | Qui fa servir què | Què aconsegueix | Objectiu (mòdul 1) |
|---|---|---|---|
| Xifrar cap al propietari | Qualsevol xifra amb la pública; només el propietari desxifra amb la privada | Que només el destinatari pugui llegir | Confidencialitat |
| Signar pel propietari | El propietari signa amb la privada; qualsevol verifica amb la pública | Que qualsevol pugui comprovar qui ho ha emès | Autenticitat + no repudi |
Fixa't en l'asimetria de cada fila: en el xifratge, molts poden escriure, només un pot llegir; en la signatura, només un pot escriure, molts poden comprovar. Aquest és el mapa complet del que ofereix la clau pública — en aquesta lliçó desenvolupem només la primera fila (xifrar). La segona, la signatura digital que ens deu el no repudi promès des del mòdul 1, té la seva pròpia lliçó: 04-03.
Per a MediNube això canvia el joc: la Clínica Sol pot publicar la seva clau pública, MediNube la seva, i a partir d'aquí qualsevol pot enviar-los dades xifrades sense reunió prèvia, sense canal segur, sense secret compartit.
flowchart LR
subgraph ClinicaSol["Clínica Sol (emissor)"]
M[Missatge en clar] -->|xifra amb la PÚBLICA de MediNube| C[Xifrat]
end
C -->|xarxa insegura: qualsevol ho veu, ningú ho llegeix| D
subgraph MediNube["MediNube (destinatari)"]
D[Xifrat] -->|desxifra amb la seva PRIVADA| M2[Missatge en clar]
end
Funcions d'un sol sentit amb porta falsa
Com pot ser que conèixer la clau pública no permeti deduir la privada? La resposta són les funcions d'un sol sentit amb porta falsa (trapdoor one-way functions): operacions fàcils de calcular en una direcció i computacionalment inviables d'invertir... tret que coneguis una dada extra (la porta falsa).
La porta falsa de l'RSA és la factorització d'enters:
- Fàcil (multiplicar): donats dos nombres primers grans
piq, calcularn = p × qés instantani, fins i tot amb números de mil xifres. - Inviable (factoritzar): donat només
n, recuperarpiqés un problema per al qual no es coneix cap algorisme eficient en ordinadors clàssics. Ambnde 3072 bits, tots els ordinadors del planeta treballant junts no acabarien abans que el Sol s'apagués.
Comprova-ho tu mateix amb Python pur:
import time
p = 1000000007 # primer "petit" (10 xifres)
q = 998244353 # un altre primer
t0 = time.perf_counter()
n = p * q # direccio facil
print(f"n = {n} calculat en {time.perf_counter() - t0:.9f} s")
# La direccio dificil: donat nomes n, trobar p i q per forca bruta.
t0 = time.perf_counter()
divisor = 3
while n % divisor != 0:
divisor += 2
print(f"Factor {divisor} trobat en {time.perf_counter() - t0:.3f} s")Multiplicar triga nanosegons; factoritzar aquest n diminut de ~60 bits ja costa segons o minuts. I el cost de factoritzar creix exponencialment amb la mida, mentre que multiplicar continua sent barat. Sobre aquesta desproporció se sosté l'RSA: qui coneix p i q (la porta falsa) pot construir la clau privada; qui només veu n (part de la clau pública), no.
RSA de joguina: les matemàtiques en petit
Avís de joguina (regla d'or 1). El que segueix fa servir primers ridículament petits i omet totes les proteccions. Serveix només per entendre el mecanisme. No implementis mai l'RSA a mà en producció: fes servir
pyca/cryptography, com farem a l'apartat següent.
La generació de claus RSA segueix quatre passos:
# --- RSA DE JOGUINA: nomes per aprendre ---
# Pas 1: triar dos primers secrets p i q.
p, q = 61, 53
# Pas 2: calcular el modul n (public) i phi (secret).
n = p * q # 3233 -> part de la clau publica
phi = (p - 1) * (q - 1) # 3120 -> nomes calculable si coneixes p i q
# Pas 3: triar l'exponent public e (coprimer amb phi).
e = 17 # al mon real gairebe sempre 65537
# Pas 4: calcular l'exponent PRIVAT d, invers de e modul phi.
d = pow(e, -1, phi) # 2753 -> LA PORTA FALSA en accio
print(f"Clau publica: (n={n}, e={e})")
print(f"Clau privada: (n={n}, d={d})")Punt clau: per calcular d cal phi, i per calcular phi calen p i q. Qui només coneix n = 3233 hauria de factoritzar-lo primer. Amb n = 3233 ho fas de cap; amb n de 3072 bits, ningú no pot.
Xifrar i desxifrar són la mateixa operació amb exponents diferents — elevar mòdul n:
m = 65 # el "missatge" (un numero menor que n)
# Xifrar amb la clau PUBLICA (qualsevol pot):
c = pow(m, e, n) # 65^17 mod 3233 = 2790
print(f"Xifrat: {c}")
# Desxifrar amb la clau PRIVADA (nomes el propietari pot):
recuperat = pow(c, d, n) # 2790^2753 mod 3233 = 65
print(f"Desxifrat: {recuperat}")
assert recuperat == mFunciona pel teorema d'Euler: (m^e)^d = m^(e·d) ≡ m (mod n) quan e·d ≡ 1 (mod phi). No necessites dominar la demostració; necessites la intuïció: elevar a e embolica el missatge; només l'exponent d — que exigeix la porta falsa — el desembolica.
Observa també la limitació estructural: el "missatge" és un número menor que n. L'RSA no xifra fluxos de dades; xifra un número de mida acotada. Guarda't aquesta dada: serà central a l'apartat 6.
RSA real amb pyca/cryptography
Al món real la generació de claus té dotzenes de subtileses (primers segurs, tests de primalitat, primers amb distància adequada...). Tot això ho resol pyca/cryptography:
from cryptography.hazmat.primitives.asymmetric import rsa
clau_privada = rsa.generate_private_key(
public_exponent=65537, # l'estandard de facto; no el canviis
key_size=3072, # bits del modul n
)
clau_publica = clau_privada.public_key()
print(clau_privada.key_size) # 3072
print(clau_publica.public_numbers().e) # 65537
print(clau_publica.public_numbers().n.bit_length()) # 3072public_exponent=65537: laedel nostre joguina. 65537 (2¹⁶+1) és el valor universal: fa el xifratge ràpid sense afeblir res. No hi ha motiu per fer-ne servir un altre.key_size: la mida denen bits, que defineix la seguretat. 2048 bits és el mínim acceptable avui (~112 bits de seguretat); 3072 o més és el recomanat per a sistemes nous (~128 bits de seguretat, el nostre estàndard del curs segons la regla d'or 5). Per sota de 2048, trencat o al límit: prohibit.- L'objecte
clau_privadaconté la pública (es deriva d'ella ambpublic_key()); el contrari és impossible — aquesta és tota la gràcia.
Per què l'RSA "de llibre de text" és insegur: farciment OAEP
El nostre joguina feia c = m^e mod n directament sobre el missatge. Això s'anomena RSA de llibre de text (textbook RSA) i és insegur per diverses vies independents:
- És determinista. El mateix missatge produeix sempre el mateix xifrat. Un atacant que sospiti que el missatge és
"POSITIU"o"NEGATIU"no necessita desxifrar res: xifra tots dos candidats amb la clau pública (que és pública!) i compara. És el mateix pecat que el mode ECB de 02-02 — el determinisme filtra informació. - És maleable. Per les propietats de les potències,
c · (2^e) mod ndesxifra a2m: un atacant pot transformar el xifrat de manera predictible sense conèixer-lo. - Els missatges petits són fràgils. Amb
epetit i missatges curts sense farciment, hi ha atacs algebraics directes.
La solució és el farciment OAEP (Optimal Asymmetric Encryption Padding): abans d'aplicar l'operació RSA, el missatge s'expandeix amb farciment aleatori i estructurat. Resultat: cada xifrat és diferent encara que el missatge es repeteixi, la maleabilitat es detecta i els atacs algebraics desapareixen. L'OAEP és a l'RSA el que el GCM era a l'AES: la manera correcta de fer servir la primitiva.
Veiem-ho amb el fil del curs: la Clínica Sol envia a MediNube un avís curt xifrat, sense clau compartida prèvia:
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
# MediNube va generar el seu parell a l'apartat anterior i va publicar clau_publica.
# La Clinica Sol nomes necessita aquesta clau publica:
missatge = b"Alta de pacient ana.perez confirmada - Clinica Sol"
oaep = padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()), # funcio de mascara interna
algorithm=hashes.SHA256(), # hash de l'esquema OAEP
label=None, # gairebe mai s'usa; deixa'l a None
)
xifrat = clau_publica.encrypt(missatge, oaep)
print(len(xifrat)) # 384 bytes: SEMPRE la mida de n (3072 bits)
# Nomes MediNube, amb la privada, pot desxifrar:
recuperat = clau_privada.decrypt(xifrat, oaep)
print(recuperat.decode())Punts a interioritzar:
- El farciment es passa explícitament en cada
encrypt/decrypt, i ha de ser el mateix als dos costats. Apyca/cryptographyno existeix un "RSA sense farciment" accessible per accident — bé. - Cada execució produeix un xifrat diferent (pel farciment aleatori). Executa
encryptdues vegades amb el mateix missatge i compara: no coincideixen, i tots dos desxifren bé. - El xifrat ocupa sempre la mida del mòdul (384 bytes amb clau de 3072), tant se val que el missatge tingui 5 bytes o 300.
- Existeix un farciment més antic, PKCS#1 v1.5, encara present en protocols heretats. Per xifrar, té un historial d'atacs (Bleichenbacher, 1998, i les seves reencarnacions): en codi nou, OAEP sempre.
Els límits fonamentals de l'RSA: mida i velocitat
Ja has vist al joguina que l'RSA xifra "un número menor que n". Amb OAEP, el farciment consumeix part d'aquest espai; el màxim real és mida_clau - 2·mida_hash - 2 bytes:
maxim = clau_publica.key_size // 8 - 2 * (256 // 8) - 2
print(maxim) # 318 bytes amb clau de 3072 i OAEP-SHA256
historial_complet = b"X" * 50_000 # un historial medic real
try:
clau_publica.encrypt(historial_complet, oaep)
except ValueError as e:
print("FALLA:", e) # el missatge no hi capI a més de petit, és lent. Comparat amb la criptografia simètrica del mòdul 2:
| RSA-3072 + OAEP | AES-256-GCM | |
|---|---|---|
| Mida de clau | 3072 bits (i creix malament: 128 bits de seguretat exigeixen 3072; 256 exigirien ~15360) | 256 bits |
| Missatge màxim per operació | 318 bytes | A la pràctica, gigabytes |
| Velocitat de xifratge | Milers d'operacions/s (desxifrar, encara menys) | Gigabytes per segon amb AES-NI: milers de vegades més ràpid |
| Expansió del xifrat | Tot missatge es converteix en 384 bytes | missatge + 12 (nonce) + 16 (tag) |
| Necessita secret compartit previ | No | Sí |
Conclusió que has de retenir: l'RSA no serveix per xifrar dades; serveix per xifrar claus. El patró universal és fer servir l'asimètrica per fer arribar una clau simètrica petita, i la simètrica (AES-GCM) per a les dades de veritat. Aquest patró — el xifratge híbrid — és exactament la lliçó 04-05, on MediNube enviarà exports complets d'historials combinant el millor de tots dos mons. Per ara, queda't amb la restricció.
Serialització de claus: el format PEM
Un objecte RSAPrivateKey viu a la memòria d'un procés Python. Per desar-lo a disc, enviar la pública a una clínica o carregar-lo en arrencar, cal serialitzar-lo. El format universal és PEM: els bytes de la clau codificats en Base64 entre capçaleres -----BEGIN...----- (recorda 01-02: Base64 codifica, no xifra — per això la privada, a més, es xifra amb una passphrase).
from cryptography.hazmat.primitives import serialization
# --- Clau PRIVADA: SEMPRE xifrada amb passphrase en desar-la ---
pem_privada = clau_privada.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8, # el format modern estandard
encryption_algorithm=serialization.BestAvailableEncryption(
b"passphrase-llarga-de-veritat-no-esta" # en real: d'un gestor de secrets
),
)
print(pem_privada.decode()[:70]) # -----BEGIN ENCRYPTED PRIVATE KEY-----
# --- Clau PUBLICA: sense xifrar, es publica ---
pem_publica = clau_publica.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo, # l'estandard
)
print(pem_publica.decode()[:30]) # -----BEGIN PUBLIC KEY-----
# --- Carregar de nou ---
privada2 = serialization.load_pem_private_key(
pem_privada, password=b"passphrase-llarga-de-veritat-no-esta"
)
publica2 = serialization.load_pem_public_key(pem_publica)PKCS8és el format contenidor modern per a privades (també veuràs l'heretat "TraditionalOpenSSL"; per a codi nou, PKCS8).BestAvailableEncryption(passphrase)xifra el PEM privat amb el millor que ofereixi la llibreria. Una privada al disc sense xifrar és un secret nu: qui llegeixi el fitxer és MediNube. La passphrase, com vas aprendre a 02-04, passa per una KDF abans de convertir-se en clau — la llibreria ho fa per tu.SubjectPublicKeyInfoés el format estàndard de públiques; el seu nom ve del món dels certificats X.509, que trepitjarem al mòdul 5.- On desar el PEM privat i la seva passphrase en producció (permisos, gestor de secrets, HSM, rotació) és matèria del mòdul 6; aquí la disciplina mínima: privada xifrada, passphrase fora del repositori.
La pregunta incòmoda: de qui és aquesta clau pública?
Tanquem amb el cap solt més important. El flux complet va ser: MediNube genera el seu parell, publica pem_publica, i la Clínica Sol xifra cap a aquesta clau. Però posa't a la pell del desenvolupador de la Clínica Sol que rep per correu un fitxer medinube_publica.pem. Com sap que aquesta clau és realment de MediNube?
Un atacant a la xarxa (o que compromet el correu) pot interceptar el PEM i substituir-lo per la seva pròpia clau pública. La clínica xifraria cap a l'atacant, aquest desxifraria, llegiria l'historial, el tornaria a xifrar amb la pública autèntica de MediNube i el reenviaria. Ningú no notaria res: el xifratge "funciona" a tots dos trams. La confidencialitat matemàtica és perfecta; la identitat de la clau és l'anella trencada.
La criptografia asimètrica resol la distribució de claus de xifratge... i a canvi crea el problema de la distribució autenticada de claus públiques. Aquest problema té solució — certificats i autoritats de certificació — però requereix peces que encara no tenim, així que el deixem explícitament obert fins al mòdul 5. El tornarem a veure, amb més dramatisme, a 04-04.
Errors Comuns i Consells
- Confondre el sentit de les claus. Es xifra amb la pública del destinatari (no amb la teva) i es desxifra amb la privada pròpia. Si et descobreixes xifrant amb una privada, o estàs signant (04-03) o estàs confós.
- Implementar l'RSA a mà "perquè les matemàtiques són senzilles". El joguina d'aquesta lliçó omet generació segura de primers, farciment, protecció contra timing attacks (recorda 01-04) i una dotzena de coses més. Regla d'or 1: fes servir la llibreria.
- Claus de 1024 bits (o menys) en codi heretat. Si auditant MediNube trobes
key_size=1024, és una troballa de seguretat: factoritzable amb recursos seriosos. Mínim 2048, recomanat 3072+. - Xifrar amb PKCS#1 v1.5 en codi nou. És el farciment heretat amb historial d'atacs. Per xifrar, OAEP sempre.
- Desar la privada en PEM sense passphrase (
NoEncryption()). Hi ha casos legítims (la passphrase l'aporta un gestor de secrets extern), però per defecte:BestAvailableEncryption. - Intentar xifrar dades grans amb RSA trossejant-les. Xifrar un fitxer en blocs de 318 bytes amb RSA és lentíssim i criptogràficament delicat. El patró correcte és l'híbrid: paciència fins a 04-05.
- Donar per bona una clau pública rebuda per un canal insegur. Acabes de veure per què. Fins al mòdul 5, com a mínim verifica'n l'empremta (hash SHA-256 del PEM, com a 03-01) per un segon canal.
Exercicis
-
Joguina completa. Amb
p = 11,q = 19ie = 7, calcula a mà (amb ajuda de Python per apow) els valorsn,phiid; xifra el missatgem = 8i comprova que desxifra bé. Per què un atacant que veun = 209ie = 7triga segons a trencar-ho, i amb unnde 3072 bits no pot? -
El pecat del determinisme. Escriu una funció
endevinar_resultat_MALAMENT(xifrat, clau_publica)que demostri l'atac a l'RSA de llibre de text: fent servir l'RSA de joguina (sense farciment), i sabent que el missatge només pot ser1("POSITIU") o0("NEGATIU"), recupera el missatge sense conèixer la clau privada. Explica per què l'OAEP fa impossible aquest atac. -
Intercanvi de PEMs. Simula l'arrencada de la integració MediNube ↔ Clínica Sol: (a) genera el parell RSA-3072 de MediNube i serialitza'l (privada amb passphrase, pública en clar); (b) "envia" la pública a la Clínica Sol (una variable), que la carrega amb
load_pem_public_keyi xifra amb OAEP el missatgeb"Sol.licitud d'acces a l'historial de ana.perez"; (c) MediNube carrega la seva privada des del PEM amb la passphrase i desxifra. (d) Calcula el màxim de bytes xifrables i comprova ambtry/exceptquè passa en xifrar un missatge de 400 bytes.
Solucions
p, q, e = 11, 19, 7 n = p * q # 209 phi = (p - 1) * (q - 1) # 180 d = pow(e, -1, phi) # 103 (7·103 = 721 = 4·180 + 1) c = pow(8, e, n) # 8^7 mod 209 = 137 assert pow(c, d, n) == 8 # 137^103 mod 209 = 8 ✔
Amb n = 209, l'atacant prova divisors i factoritza a l'instant (209 = 11 × 19), reconstrueix phi = 180 i calcula d igual que el propietari. Amb 3072 bits, la factorització no és "més lenta": és inviable — el cost creix de manera superpolinòmica amb la mida, i no existeix cap algorisme clàssic eficient. La seguretat de l'RSA és exactament la duresa d'aquest problema.
def endevinar_resultat_MALAMENT(xifrat, n, e):
# L'atacant xifra els DOS candidats amb la clau publica i compara.
for candidat in (0, 1):
if pow(candidat, e, n) == xifrat:
return "POSITIU" if candidat == 1 else "NEGATIU"
c = pow(1, 7, 209) # la clinica xifra "POSITIU"
print(endevinar_resultat_MALAMENT(c, 209, 7)) # POSITIU — sense tocar la privadaL'atac funciona perquè l'RSA de llibre de text és determinista: xifrar el mateix missatge dona sempre el mateix resultat, i l'atacant pot xifrar (la clau és pública). L'OAEP afegeix farciment aleatori a cada xifratge: els dos xifrats d'un mateix candidat mai no coincideixen, així que comparar no diu res. (De propina: pow(0, e, n) == 0 i pow(1, e, n) == 1 — el llibre de text ni tan sols amaga el 0 i l'1!)
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa, padding
# (a) MediNube
priv = rsa.generate_private_key(public_exponent=65537, key_size=3072)
pem_priv = priv.private_bytes(
serialization.Encoding.PEM, serialization.PrivateFormat.PKCS8,
serialization.BestAvailableEncryption(b"frase-de-medinube"))
pem_pub = priv.public_key().public_bytes(
serialization.Encoding.PEM, serialization.PublicFormat.SubjectPublicKeyInfo)
# (b) Clinica Sol
oaep = padding.OAEP(mgf=padding.MGF1(hashes.SHA256()),
algorithm=hashes.SHA256(), label=None)
pub_clinica = serialization.load_pem_public_key(pem_pub)
xifrat = pub_clinica.encrypt(b"Sol.licitud d'acces a l'historial de ana.perez", oaep)
# (c) MediNube
priv2 = serialization.load_pem_private_key(pem_priv, password=b"frase-de-medinube")
print(priv2.decrypt(xifrat, oaep))
# (d) Limit
print(3072 // 8 - 2 * 32 - 2) # 318 bytes
try:
pub_clinica.encrypt(b"X" * 400, oaep)
except ValueError as e:
print("FALLA:", e) # Data too long / Encryption failedEl pas (b) conté el parany conceptual de l'exercici: la Clínica Sol accepta pem_pub sense verificar de qui és. Funciona, però és el forat de l'últim apartat — mòdul 5.
Conclusió
Has creuat la frontera conceptual del curs. La criptografia asimètrica substitueix el secret compartit per un parell de claus: la privada mai no surt de casa; la pública es reparteix sense por. El seu fonament són les funcions d'un sol sentit amb porta falsa — per a l'RSA, multiplicar primers és fàcil i factoritzar el producte és inviable —, i ho has vist per dins amb un RSA de joguina (d = pow(e, -1, phi)) i per fora amb el real: rsa.generate_private_key (3072 bits recomanat), farciment OAEP obligatori perquè l'RSA "de llibre de text" és determinista i maleable, i serialització PEM amb la privada sempre xifrada (BestAvailableEncryption). També coneixes els seus dos límits: només xifra missatges diminuts (318 bytes amb clau de 3072) i és milers de vegades més lent que l'AES — l'RSA xifra claus, no dades (l'híbrid arriba a 04-05) —, i arrossega una pregunta sense resposta: com saps de qui és una clau pública? (mòdul 5). Però abans de resoldre res d'això cal parlar d'un problema pràctic: les claus RSA són enormes i creixen fatal — per a 256 bits de seguretat farien falta ~15360 bits de clau. Existeix una altra família de portes falses que dona les mateixes garanties amb claus de només 256 bits, i és la que domina la criptografia moderna, del teu mòbil al TLS. És la criptografia de corba el·líptica, i t'espera a la propera lliçó, 04-02. 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
