Este o idee proastă să vă proiectați propriul hash de parolă.
Realizarea de funcții criptografice este încă un proces de încercare și eroare. Sigur, de-a lungul timpului am dat peste niște lucruri care sunt o idee bună sau chiar obligatorii. Și cu siguranță am învățat o mulțime de lucruri care nu muncă. Dar nu știm cum să facem lucrurile care s-au dovedit sigure până la capăt. O mică greșeală foarte subtilă poate face ca un construct criptografic să eșueze catastrofal. Și sunt mult de oportunităţi pentru astfel de greşeli. Voi numi câteva mai târziu.
Cel mai bun lucru pe care îl putem face acum este ca oamenii cu experiență în acest domeniu să facă un lucru cripto, apoi toată lumea încearcă să spargă acel lucru cripto. Dacă toată lumea încearcă suficient și nu reușește la asta pentru o lungă perioadă de timp, atunci avem ceva care este probabil suficient de bun. Încă nu putem dovedi absența problemelor, dar dacă mii de criptoanaliști nu au putut, atunci sperăm că și următoarea mie nu pot.
Dar chiar și asta eșuează din când în când. Uneori, după ani, chiar decenii, o problemă critică se găsește în ceva care a fost cercetat de cei mai deștepți oameni timp de secole. De aceea MD5 nu mai este considerat OK și de ce RC4 este considerat problematic. Sau peisajul se schimbă, conducând de ex. la nevoia de săruri în hash-urile parolelor și funcții de hash lente intenționat.
Utilizând cei mai cunoscuți algoritmi criptografici actuali, putem valorifica această experiență colectivă și, probabil, evităm repetarea greșelilor din trecut. S-ar putea să se descopere noi greșeli, dar asta nu poate fi evitat. Cineva care își construiește propriile funcții cripto, este probabil să repete unele dintre aceste greșeli sau să creeze altele complet noi.
Știu, știu, este distractiv să proiectezi singur chestia asta. Și este bine să construiești ceva care să se simtă în siguranță. Stack Exchange este plin de întrebări despre criptarea personalizată și (în special) hash-uri de parole. Problema este că este ușor să construiești ceva pe care tu însuți nu poți rupe. Dar asta nu înseamnă că alții nu pot.Această zicală este străveche și apare destul de des încât acum este cunoscut ca legea lui Schneier.
Ce poate merge rau?
Deci, pot exista probleme cu nucleul unui algoritm criptografic. Acesta este ceea ce a spart MD5 și RC4.
Sau algoritmul poate fi complet ok, dar o implementare poate fi ruptă. Aceasta poate fi o simplă eroare sau poate fi ceva mai subtil, cum ar fi a atac pe canalul lateral (care sunt surprinzător de dificil de evitat uneori).
Dar este, de asemenea, posibil (ușor, chiar) ca primitivele criptografice sigure cu implementări fără erori să fie utilizate incorect, făcând sistemul nesigur. De exemplu, folosind corect criptarea și semnăturile digitale, dar făcând presupuneri naive în timpul unei strângeri de mână de comunicare (SSL a avut parte de probleme cu aceasta). Un alt exemplu binecunoscut este AES-ECB, care utilizează AES perfect fin într-un mod care poate scurge informații semnificative.
În funcția ta hash?
Propria ta funcție de hashing a parolei cade pradă, de asemenea, la ceva de genul acesta aici:
repeta 100_000:
hash = sha512(hash)
SHA-512 este perfect în regulă (din câte știm). Folosirea lui în felul acesta este descurajată.
SHA-512 generează o ieșire de 512 biți „nedistingebilă de aleatorie” pentru fiecare intrare. Poate genera aceeași ieșire pentru două intrări distincte, aceasta se numește coliziune. Problema este că funcțiile hash pe N-biți pe intrările pe N-biți nu sunt în general bijectiv. Aceasta înseamnă că atunci când se alimentează o ieșire SHA-512, unele dintre valorile posibile de 512 biți se vor ciocni cu altele, producând aceeași ieșire. De necesitate, aceasta înseamnă, de asemenea, că alte valori hash nu pot fi generate deloc.
Să ne uităm la cum funcționează acest lucru pentru SHA-512, trunchiat la 4 biți. Mai exact, luăm primul octet de la ieșire și scoatem la zero cei 4 biți înalți din acest octet. Octetul unic rezultat este folosit ca intrare în runda următoare. Diferite moduri de selectare a biților dau rezultate diferite, dar principiul este același.
Încercarea tuturor celor 16 intrări posibile pentru mai multe runde ne oferă aceste lanțuri:
în 1. 2. 3. 4. 5. 6. 7.
00 -> 08 -> 06 -> 08 -> 06 -> 08 -> 06 -> 08
06 -> 08 /
07 -> 06 -> 08 -> 06 -> 08 -> 06 -> 08 -> 06
08 -> 06 /
03 -> 04 -> 05 \
13 -> 15 -> 05 -> 09 -> 02 -> 10 -> 14 -> 14
04 -> 05 -> 09 -> 02 -> 10 -> 14 -> 14 /
15 -> 05 -> 09 -> 02 -> 10 -> 14 /
05 -> 09 -> 02 -> 10 -> 14 -> 14
01 -> 11 -> 02 -> 10 -> 14 /
09 -> 02 -> 10 -> 14 -> 14
11 -> 02 -> 10 -> 14 /
02 -> 10 -> 14 -> 14
12 -> 10 / /
10 -> 14 -> 14
14 -> 14 /
După doar 6 runde, cele 16 ieșiri posibile au fost reduse la doar 3. Același efect poate fi văzut pentru trunchieri mai mari. Am rulat câteva simulări pentru SHA-512 trunchiate la primul 1 octet (2â¸), 2 octeți (2¹â¶) și 3 octeți (2²â´):
octeți: 1 2 3
spațiu de intrare: 256 65536 16777216
converge către valori M: 13 330 2765
după N runde: 31 518 7114
Puteți observa că efectul de convergență este prezent în toate cele trei scenarii. În ceea ce privește SHA-512 netăiat, computerul meu nu este suficient de rapid pentru a calcula acest lucru, nu am putut găsi nicio informație despre puterea și certitudinea efectului și nu sunt suficient de inteligent pentru a construi o dovadă (dacă o dovadă este chiar posibil). Dar șansele sunt că veți vedea efectul și în SHA-512 complet. Instinctul meu suspectează că reduce spațiul hash cu rădăcina pătrată (înjumătățirea lungimii biților), dar aș putea greși foarte mult [actualizare: vezi linkurile furnizate în comentarii: unu, Două, Trei]. 100.000 runde limitează probabil și daunele.
Acum, asta vă dăunează cu adevărat hașul? Probabil ca nu. Dar este o slăbiciune, una pe care funcțiile hash de parole din lumea reală au grijă să o evite (de exemplu, asigurându-se că parola și sarea sunt amestecate înapoi în mod regulat).
Cred că acesta este un exemplu grozav al capcanelor subtile din proiectarea cripto. Este atât de ușor să ratezi așa ceva. De aceea recomand să folosiți un algoritm testat în luptă. Sunt mai bune decât orice putem veni cu tine sau cu mine.
Celelalte răspunsuri fac deja câteva recomandări pentru ce hashuri să folosească; Bine: pbkdf2, bcrypt. Mai bine: argon2, scrypt. Am auzit că Balonul este un lucru, dar nu știu nimic despre el, așa că nu am o părere despre el.