Hash, sal, bcrypt i Argon2: què fa amb la teva contrasenya un lloc ben fet

Publicat el per David Carrero

Un lloc ben fet no sap la teva contrasenya. No és que no vulgui: és que no pot.

Sona a trampa, perquè cada vegada que l’escrius el sistema et deixa passar, i per deixar-te passar ha de comprovar alguna cosa. Però comprovar no és saber. El servidor guarda una empremta calculada a partir de la teva contrasenya; quan l’escrius, torna a calcular l’empremta i compara. Si coincideixen, endavant. En cap moment cal que la contrasenya estigui escrita enlloc.

D’aquí surt el senyal més clar per distingir un servei seriós d’un que no ho és: si quan l’oblides te l’envien per correu, la tenien guardada. I el que està guardat acaba, tard o d’hora, a les mans d’algú altre.

1979 la idea de no guardar-les — i la de fer-ho a poc a poc

El 1979, Robert Morris i Ken Thompson van publicar a Communications of the ACM «Password Security: A Case History», explicant el que havien fet a Unix. És un relat del que van aprendre, i hi queden assentades dues idees que avui donem per evidents.

La primera no la van inventar ells —guardar el hash en lloc de la contrasenya ja es feia abans—, però la van explicar millor que ningú: no guardar la contrasenya, guardar-ne el hash. Una funció que converteix la teva contrasenya en un valor d’aspecte arbitrari i que no es pot desfer: del hash no es torna a la contrasenya.

La segona sí que és seva: la sal. Un valor aleatori diferent per a cada usuari, que es barreja amb la contrasenya abans de calcular el hash. Sense sal, dues persones amb la mateixa contrasenya tenen el mateix hash —el fitxer robat es converteix en un joc de buscar repetits— i, pitjor, algú pot precalcular una taula gegant una sola vegada i fer-la servir contra totes les bases de dades del món. La sal no fa que la teva contrasenya sigui més difícil d’endevinar: fa que endevinar-la no serveixi a ningú més.

Però en aquell mateix article hi ha una tercera idea, molt menys citada, i és la que importa aquí: van fer la funció deliberadament lenta. No per descuit. A posta. Xifrar una contrasenya costava molt més del que tècnicament calia, perquè a qui hi entra un cop cada matí tant li fa, i a qui prova milions de candidates no.

Tot l’assumpte hi cap en una frase de fa gairebé cinquanta anys.

Per què la lentitud és l’única defensa honesta

Gairebé totes les defenses informàtiques són asimètriques: costen poc a qui es defensa i molt a qui ataca. Xifrar és barat; desxifrar sense la clau és inviable. El defensor juga amb avantatge estructural.

L’emmagatzematge de contrasenyes, no. Aquí defensor i atacant executen exactament la mateixa funció. Tu calcules el hash per comprovar que l’has encertada; ell el calcula per comprovar si l’ha encertada. És l’única cursa de la seguretat on tots dos corren amb les mateixes cames.

Quan no pots córrer més que el teu rival, només queda una jugada: encarir la pista per a tots dos. Tu pagues aquest cost un cop per inici de sessió. Ell, un cop per intent. Com que necessita ordres de magnitud més intents que tu, la mateixa factura us afecta de manera incomparable. Això és el que fa un hash de contrasenyes.

Per això les funcions ràpides i boníssimes per a altres coses —SHA-256, per exemple— són una tria pèssima aquí. Són ràpides. Ràpid és exactament el que no volem.

1999 bcrypt, i el cost com a peça ajustable

El problema d’una funció lenta és que el maquinari no s’està quiet. El que el 1979 era lent, després és instantani. Una defensa calibrada contra els ordinadors d’una dècada envelleix sola, sense que ningú hi toqui.

El 1999, Niels Provos i David Mazières van presentar bcrypt a la USENIX Annual Technical Conference, amb un títol que ja ho diu tot: A Future-Adaptable Password Scheme.

La idea: que el cost no sigui a la funció, sinó en un paràmetre. bcrypt porta un factor de cost que decideixes tu i que es guarda al costat del hash. Si el maquinari es torna molt més ràpid, apuges el número i les contrasenyes noves tornen a costar el que han de costar, sense canviar d’algorisme.

És un disseny que assumeix la seva pròpia obsolescència i s’hi prepara. Hi ha poquíssim programari que faci això.

2009 scrypt, i el descobriment que el temps no n’hi ha prou

bcrypt encareix el temps de càlcul, i va funcionar. Fins que l’atacant va deixar d’utilitzar el mateix tipus de màquina que el defensor.

Un servidor té uns quants nuclis ràpids i de propòsit general. Una GPU té una barbaritat de nuclis petits fent el mateix en paral·lel, i un ASIC va més enllà: silici fabricat per executar una sola operació. Si la teva defensa consisteix a dir «aquesta operació costa X», algú pot construir maquinari que faci moltes X alhora. El defensor continua amb el seu servidor.

El 2009, Colin Percival va presentar scrypt amb un altre argument: Stronger Key Derivation via Sequential Memory-Hard Functions. Si el cost és només en el càlcul, es paral·lelitza. Però la memòria no la regala ningú. Obliga la funció a fer servir molta RAM i a recórrer-la de manera que no es pugui esquivar, i de sobte l’atacant no pot multiplicar nuclis: cada nucli necessitaria la seva pròpia memòria. I els nuclis d’una GPU tenen molta potència i molt poca RAM per a cadascun.

Percival no va encarir l’operació. Va encarir el maquinari necessari per repetir-la en massa. És un canvi de nivell: s’ataca el pressupost de l’atacant, no el seu rellotge.

2015 Argon2, i el final del debat

Que hi hagués diverses opcions raonables no ajudava ningú a triar. Així que la comunitat criptogràfica va fer el que sol fer quan vol tancar un tema: un concurs públic. La Password Hashing Competition va rebre candidats, els va sotmetre a anàlisi obert durant anys i el 2015 va proclamar guanyador l’Argon2.

L’Argon2 hereta les dues lliçons: cost en temps i cost en memòria, tots dos ajustables per separat, més el nombre de fils. No és màgia. És la síntesi ordenada del 1979, el 1999 i el 2009, revisada per gent la feina de la qual consistia a intentar trencar-la.

Què vol dir això per a tu

Gairebé res d’això està a les teves mans, i convé dir-ho: el hash el tria el lloc, no tu. Pots tenir la millor contrasenya del món i que te la guardin en text pla en un Excel.

Però l’altre costat de l’equació sí que depèn de tu. Tot aquest edifici —la sal, el cost, la memòria— serveix per encarir cada intent de l’atacant. El que decideix quants intents li calen és la teva contrasenya. Si és al diccionari, cap funció lenta no et salva: caurà entre les primeres. Si és llarga i no s’assembla a res, aquest preu per intent es multiplica per un nombre d’intents que no cap en el temps disponible.

Per això el nostre generador mesura bits d’entropia i no percentatges, i per això el comprovador busca la teva contrasenya als diccionaris abans de comptar símbols. Ells posen el preu per intent; tu poses el nombre d’intents. Cap de les dues meitats no funciona sense l’altra.

I sí: continua sent la mateixa pregunta de sempre. Només que ara, a l’altre costat, algú intenta respondre-la moltes vegades per segon, i des del 1979 que mirem que cadascuna d’aquestes vegades li costi diners.


Fonts: R. Morris i K. Thompson, «Password Security: A Case History», Communications of the ACM, 1979 · N. Provos i D. Mazières, «A Future-Adaptable Password Scheme», USENIX Annual Technical Conference, 1999 (bcrypt) · C. Percival, «Stronger Key Derivation via Sequential Memory-Hard Functions», 2009 (scrypt) · Password Hashing Competition, guanyador Argon2, 2015.

← Tornar al blog