Funció de hash

Imagina que et registres a una pàgina web i has d’omplir el típic formulari on un dels camps és introduir la contrasenya que vols que tingui el teu compte. Una vegada tot ple, cliques el botó d’enviar i reps confirmació al teu email de que el compte s’ha creat correctament.

Molta gent es pensa que la contrasenya es guarda xifrada juntament amb totes les teves altres dades d’usuari. No podrien estar més equivocats, ja que si s’emmagatzemés xifrada voldria dir que qualsevol administrador de sistema podria llegir la teva contrasenya en clar. És més, si un atacant comprometés i robés tota la base de dades, seria capaç d’utilitzar la teva contrasenya a tots els llocs on t’has registrat (suposant clar que utilitzis la mateixa contrasenya a diferents llocs web).

Aquí entra en joc una funció anomenada hash. Les funcions de hash són algorismes que donada una cadena de text, la converteix a una cadena de longitud fixe que pot semblar aleatòria. La gràcia d’aquesta funció és que és molt fàcil obtenir el hash d’una cadena de text però matemàticament impossible obtenir la cadena inicial a partir del hash.

A més a més, independentment de la longitud inicial de la cadena, el hash sempre tindrà la mateixa mida i sempre canviarà completament encara que modifiquis només una lletra. Evitant així que puguis arribar a correlacionar hashes:

projectenadki:     b7e1bdcf56567c2252cda827c462a5740982e0d13b5bbfdd4ae2f78d554b3117

projectenadki1: 9e6d55578847bc4a09711f260558eebd9fabf97223d3b1a7219cd649e92b2246

test:             9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08

A continuació, pots veure el resultat d’aplicar diferents tipus de funcions de hash a la cadena de text projectenadki:

MD5: 79e060dc3fd4088d5aaf7
SHA1: d7716c2cd1a1e8e248305fd6a7a19953f9823e6a
SHA256: b7e1bdcf56567c2252cda827c462a5740982e0d13b5bbfdd4ae2f78d554b3117
SHA512: a3cec5a6168f3991a5060299fd395f0a4fa5ff5cdd632265bff3f1218290aaa02a2b599fc9d11ec9a8edb4477e2c117c094cde360a7719685284854fdbc5eae6
Bycript: $2a$12$41Xjf9hQRMgfG8wm638qmed6JaWjgCY5rLDgn0PhQ54Yo9uTBRlU.

No tots els hashes són iguals. Normalment es recomana utilitzar algorismes de hash com PBKDF2, scrypt i bcrypt, que són considerats més segurs. Algorismes com MD5 i SHA1 s’han d’evitar sempre ja que és poden crackejar més fàcilment.

Llavors, si el que es guarda a la base de dades no és la contrasenya sinó el hash d’aquesta, com ho fa la pàgina web per poder comprovar que la contrasenya que has posat a l’iniciar la sessió és la correcte o no? Doncs primer passa la contrasenya introduïda per l’usuari per la funció de hash i en compara el resultat amb el que té guardat a la base de dades. Si són els mateixos, vol dir que les contrasenyes són exactament iguals.

Problemàtica

Tot i que el valor que es guarda és el hash i no la contrasenya en text clar, no et pensis que està més segura. Quan un atacant aconsegueix robar tota la base de dades, pot utilitzar diversos tipus d’atacs per aconseguir crackejar les contrasenyes.

Comentar que per trencar hashes pots utiltizar moltes eines. Les més famoses són hashcat i John the Ripper.

Una tècnica que podria utilitzar l’atacant és la coneguda com a rainbow tables o atacs de diccionari. Per posar un exemple més fàcil, utilitzaré un atac de diccionari. Imagina que a la base de dades hi ha 1.000 usuaris i les seves contrasenyes han passat per la funció de hash del tipus SHA256.

El que farà l’atacant és agafar la primera paraula del seu diccionari d’1 milió de contrasenyes, que estan en text clar, li aplica el SHA256 i ho compara amb tots els hashes de la base de dades. En aquest cas, l’atacant necessita molt poca capacitat de computació (valors aproximats calculats per SHA256 amb un ordinador i7):

Diccionari: 1.000.000 (10^6) paraules
Base dades: 1.000 (10^3) hashes
Temps computació: 500ms per cada milió de hashes
Total operacions (pitjor dels casos): 10^6 operacions, ja que només ha de calcular cada hash una vegada
Total temps: 10^6 * 500ms/milió = 500ms

Per tant, en només mig segon seria capaç de saber quines de les contrasenyes estan al diccionari i per tant, obtindria el seu valor en text clar.

Salt

Una mesura molt necessària i que la majoria de normatives de seguretat obliguen a utilitzar, és la coneguda com a Salt.

La tècnica de Salting consisteix en concatenar a davant o darrere de la contrasenya una sèrie de caràcters abans de passar-la per la funció de hash. És important que els caràcters siguin únics i aleatoris utilitzant una funció de generació de caràcters aleatoris forta. A més a més el Salt no s’ha de reutilitzar i s’ha de canviar sempre que es modifiqui el la contrasenya.

Contrasenya: projectenadki
Salt: hdkoguujbk
Format: salt+contrasenya
Concatenat: hdkoguujbkprojectenadki
Hash SHA256: d46c9e549fc5c672354562b6223e00f77e99aed77678a731780c543857f3735f

Coses a tenir en compte quan utilitzes Salt:

  • Mai reutilitzar el salt. Si dos usuaris tenen el mateix salt, el hash seria el mateix si ambdós usuaris utilitzen la mateixa contrasenya.
  • Com més curts siguin els salt, més fàcil serà construir una rainbow table.
  • Mai utilitzis el nom de l’usuari com a salt, ja que passa a ser molt fàcil construir la rainbow table.

Per tant, a la base de dades hi haurà una columna nova anomenada salt. Cada usuari tindrà el seu nom d’usuari, el salt utilitzat i el hash de la contrasenya. Durant l’autenticació, el servidor haurà de concatenar el salt amb la contrasenya introduïda per l’usuari, aplicar el hash i després fer la comparació.

Un atacant que vulgui intentar crackejar les contrasenyes li serà molt més complicat, ja que haurà de computar cada contrasenya del diccionari per cada usuari, ja que els salts són diferents per cada un d’ells:

Diccionari: 1.000.000 (10^6) paraules
Base dades: 1.000 (10^3) hashes
Temps computació: 500ms per cada milió de hashes
Total operacions (pitjor dels casos): 10^6 * 10^3 = 10^9 operacions
Total temps: 10^9 * 500ms/milió = 500.000ms

L’atacant tardarà 500 segons (uns 8 minuts) en comprovar totes les contrasenyes del diccionari. Pot semblar poc temps, però pensa que hem passat de 0.5 segons a 500 i per aquest exemple estic utilitzant valors petits.

Normalment, les bases de dades poden tenir milions d’usuaris i els diccionaris que s’utilitzen poden ser de més de 50 milions de contrasenyes (tirant curt). Per tant, el temps creixeria exponencialment.

Pepper

Una altra mesura que pots aplicar és l’anomenat Pepper (pebre). Pepper també és una cadena de caràcters aleatòria que es concatena a la contrasenya just abans d’aplicar la funció de hash. La diferència clau entra el salt i el pepper és que el salt és únic i s’emmagatzema juntament amb el hash de cada usuari mentre que el pepper és un valor igual per tothom que és secret i que està guardat a una altra base de dades.

Contrasenya: projectenadki
Salt: hdkoguujbk
Pepper: bHMKZeErNL6NbVi0
Format: salt+contrasenya+pepper
Concatenat: hdkoguujbkprojectenadkibHMKZeErNL6NbVi0
Hash SHA256: 3095539ac034cc9819c7acb8fb15b86fa32aab7b7cf5994ddb47ba5b690b61b8

El salt pot ser de la longitud que vulguis sempre i quan sigui un únic valor (més longitud, més seguretat), mentre que el pepper hauria de ser de com a mínim 112 bits per considerar-se segur, segons NIST.

Afegir pepper a les contrasenyes és útil només si l’atacant no el coneix, ja que actua com una capa extra de protecció. L’atacant que comprometi la base de dades a través d’una vulnerabilitat d’injecció SQL per exemple, no podrà obtenir el pepper si està guardat a un altre ordinador o xifrat a una altra base de dades.

Coses a tenir en compte:

  • El pepper ha de tenir com a mínim 112 bits.
  • No serveix de res utilitzar pepper i no salt, ja que dos usuaris amb la mateixa contrasenya, tindran el mateix hash.
  • Si l’atacant coneix el pepper, aquest passa a ser inútil.

Conclusions

Les bases de dades haurien de guardar les contrasenyes sempre amb una funció de hash que es consideri forta i aplicant salt. A més a més, si vols una capa de seguretat addicional, mai està de més utilitzar pepper, ja que si amb salt incrementes el temps que ha d’invertir l’atacant en crackejar les contrasenyes, amb pepper mai les podrà crackejar si no aconsegueix descobrir el valor.

A part del salt i el pepper, hi ha algorismes com Bcrypt que, com a mesura de seguretat extra, una vegada s’ha obtingut el hash, calculen el hash d’aquest hash un cert nombre de vegades definit pel programa i/o l’usuari. D’aquesta manera, l’atacant a més a més d’haver d’endevinar el salt i el pepper, ha d’esbrinar quantes iteracions ha aplicat l’algorisme.

Referències

Deixa un comentari