Password hashing

Salut,

Nu stiu cati dintre voi creati si aplicatii web cu autentificare, dar am o intrebare legata de login/register.
In momentul in care user-ul se logheaza/inregistreaza, cum trimiteti parola catre server? Plain text sau o hash-uiti inainte?
De preferat ar fi ca cine raspunde sa acopere ambele cazuri : HTTP si HTTPS

Multumesc,
Andrei

pai pe https oricum nu conteza pentru ca informatia nu este in plain text, iar pe http daca incerci vreun hash local, oricum poate fi interceptat traficul daca se doreste, deci s-ar putea decripta relativ usor.

1 Like

Cu alte cuvinte, ca trimiti parola in plain text sau ca trimiti un hash, nu conteaza f mult.
Mai important e sa o hashuiesti inainte sa o stochezi in baza de date sa inteleg?

in baza de date se stocheaza ca hash pentru a nu se obtine parola in clar daca site-ul este compromis. Asa hackerii obtin un hash dar pe care nu il pot folosi pe alte site-uri pentru a accesa conturile altor useri (password recycling). Parola din input-ul de pe site se face hash server side si tot acolo se compara cu hash-ul din baza de date.

Dacă e MD5 sau SHA-1, da, se poate ghici uşor parola. Dacă e SHA256 sau bcrypt + salt + nonce, deja e cu totul alta poveste.

Conteaza. In cazul in care nu poti cripta comunicatia, macar poti sa “criptezi” secventa de autentificare. Pe de alta parte, daca folosesti hash la password-ul transmis, nu mai poti sa faci hash la parola din baza de date. Pentru mine chestia asta e mereu o dilema, vreau sa ma apăr de snifferi sau de eventualitatea ca baza mea de date sa ajunga pe mâini “necurate”? :slight_smile:

Simplu :

Nu folosi HTTP, punct, nu prea ai cum sa trimiti parola in mod sigur fara sa ai un token care sa il genereze.
O solutie ar fi sa folosesti OAuth cu Facebook/Google/GitHub, care e tot JWT, doar ca POST-ul se face mereu prin HTTPS prin alt site. Tu iei doar token-ul de autentificare, care il poti face sa expire si nu mai sunt riscuri asa mari in cazul unui man in the middle attack.

Poti genera un hash bcrypt de pe parola pe client si sa o trimiti pe aceea la server cum zice si serghei, problema e ca daca cineva foloseste o parola simpla se sparge usor cu dictionary + un bruteforce attack daca ai un FPGA (deci daca chiar vrea un guvern sa iti faca sniffing, o sa reuseasca pana la urma daca parola nu e una calumea).
Diferenta dintre bcrypt si MD5, e ca iti trebuie multa memorie pe un calculator normal si ia mult, dar cu un FPGA se poate optimiza sa fie chiar mai optim ca MD5.

1 Like

am vrut sa spun ca daca ai incerca o criptare client-side cu o cheie si un salt trimise de catre server, si ele pot fi sniffuite usor deci ar face inutila criptarea.

Token-ul se genereaza abia dupa ce te-ai logat cu succes.
Teoretic tu deja ai aflat parola la momentul ala. Atata tot ca request-urile ulterioare nu vor mai fi validate de catre server pentru ca tu n-ai token-ul…nu?

Cu ce ajuta OAuth in cazul asta?

Degeaba sunt sniffuite, acel nonce face inutila orice incercare de repetare a tentativelor de atac, pentru ca hash-ul meu este valabil o singură dată, se schimbă mereu.

Hmm, de ce crezi ca cineva nu poate lua nonce+salt-ul din sniffing si sa isi faca un script ca sa obtina direct bcrypt-ul ? (pe care dupa sa incerce sa il atace cu un FPGA sau ASIC militar cu rainbow tables de cateva sute de Tb)

Da, ai putea forta utilizatorul sa aiba o parola lunga, cu caractere speciale si atunci e foarte ok.

Pai nu ai ce face doar cu nonce-ul, ai nevoie si de parola. Practic serverul nu aşteapta parola ta, ci aşteaptă o combinaţie între nonce-ul trimis de el, şi parolă.

Şi nu e obligatoriu să ai parola lungă şi/sau complicată. Dacă pui de exemplu un delay de 3 secunde între fiecare încercare de autentificare eşuată, bruteforce-ul tău va trebui să dureze 1000 de ani. Mai mult, se poate mari delay-ul (dupa prima incercare trebuie sa astepti 3 secunde, dupa a doua 6 secunde etc).

Eu nu fac bruteforce cu serverul tau, eu iti iau hash-ul pe care il generezi pe client si il compar cu un tabel pana gasesc valoarea hash-ului. Dupa folosesc valoarea sa intru pe site-ul tau. (daca am de exemplu o baza de date uriasa cu hash-uri bcrypt, daca nu ai o parola greu de ghicit esti ars) Daca cumva folosesti nonce-ul in hash, atunci e mai greu, dar nu imposibil. Sa nu patesti ca germanii cu Enigma si Heil Hitler, cineva poate se foloseste de nonce ca sa reduca posibilele variante ale hash-ului.

Bine, nu oricine are o ditamai baza de date cu hash-uri bcrypt. Dar sigur exista servicii platite. Oricum ce zic eu se refera doar la parole simple, daca folosesti o parola gen 4$fDf$A#!%^DA#%$!^ stai linistit ca nu va fi decodata niciodata.

Ah, tu zici ca ai deja nonce-ul, si hash-ul dintre nonce si password. Ok… dar in cazul asta nu ai cum sa ai o tabela de hash-uri (cel putin, nu prefabricata), pentru ca nu stii cum va arata nonce-ul.

Uite doua referinte interesante:

Daca faci asta ca sa inveti sunt referinte bune. Daca e vre-un client care te plateste ptr. treaba asta sau lucrezi pentru vre-o firma care-si face asta in produs, sfatul meu e sa te orientezi spre ceva social login, ca sa nu mai ai atatea probleme. Si dpv al produsului e mai OK - mai degraba ma loghez undeva cu Fb/Google/GitHub decat sa-mi fac un cont si sa nu stiu cum sta treaba cu securitatea la compania respectiva.

Niste sfaturi:

  • Https peste tot. Suntem in 2017, certificatele sunt gratis, impactul de performanta e aproape 0%. N-ai de ce sa n-ai https pe tot ce misca. E o idee buna sa pui si HSTS ca sa fortezi https orice ar fi.
  • Pe partea de storage, trebuie sa folosesti un password hash - bcrypt/scrypt sau prietenii. Nu hash-uri normale. bcrypt/scrypt au si salt-uri embeduite, asa ca atacuri gen rainbow table nu sunt posibile[1]. Orice ar fi, e o idee buna sa minimizezi sansele ca baza asta de date sa fie compromisa - sa fie encryptata, sa aiba acces doar sisteme interne bine-definite etc. Ditto pentru logarea hashurilor sau a parolelor pe undeva.
  • E OK sa trimiti username si parola pe canalul https fara nicio alta procesare. In principiu hash-uri, combinatii de nonce-uri etc. sunt facute pentru canale ne-sigure ca http/ftp ca sa nu arati parola. Dar practic orice trimiti devine “parola”, iar un atacator care poate sa-ti faca mitm sau vre-un replay are aceleasi privilegii cunoscand hash-ul ca si parola.

[1] Adica ma rog, sunt posibile, dar la fel de “bune” ca un brute-force

2 Likes

Doar o mică observaţie: daca ai mai multe vhost-uri decat IP-uri, e mai complicat sa ai https pe toate (poate doar daca folosesti un certificat multi-domain - Let’s Encrypt permite asa ceva).

sni rezolva limitarea asta la nivel de protocol. Imo, versiuni vechi de internet Explorer nu suporta, dar în rest e standard.

1 Like

Interesant, m-am lovit de problema asta pe la inceputul anilor 2000, dupa care n-am mai cercetat, am luat de bun faptul ca nu poti sa ai mai multe domenii cu https pe acelasi ip :slight_smile: