Jakiego algorytmu hashowania powinienem użyć do przechowywania haseł?

0

Pytanko, bo większość tematów tego tematu ma już trochę latek, a nie wiem "co tam ostatnio złamano"

Jaki algorytm z tych jest uważany jako "bezpieczny" ?

  • MD5
  • RIPEMD160
  • SHA1
  • SHA256
  • SHA384
  • SHA512
0

Jeżeli używasz MySQL czy MariaDB to użyj AES_ENCRYPT.

0

MSSQL + EF Core

1

@Ktos:

Dzięki, KeyDerivation.Pbkdf2 to dobry kierunek :)

0

Tak. Z przedstawionych w pierwszym poście powiedziałbym, że żaden nie jest "najlepszym możliwym wyborem".

Stan dla roku 2018:

Argon2 is the winner of the password hashing competition and should be considered as your first choice for new applications;
PBKDF2 when FIPS certification or enterprise support on many platforms is required;
scrypt where resisting any/all hardware accelerated attacks is necessary but support isn’t.
bcrypt where PBKDF2 or scrypt support is not available.
https://www.quora.com/What-is-the-most-reliable-safe-and-efficient-password-hashing-algorithm-as-of-2018

0

Ok, a jakie są różnice pomiędzy HMACSHA1 HMACSHA256 HMACSHA512?

2

Nic z powyższych (może częściowo poza postem @Ktos). Obecnie jeśli chcesz użyć czegoś do haseł to ja bym szedł (w takiej kolejności):

  • bcrypt - "najdłużej" na rynku i dalej nie jest złamany. W przypadku algorytmów kryptograficznych wiek to zaleta.
  • Argon2id - nowy, ale wygląda na całkiem spoko
  • Argon2i - troszkę wolniejsza wersja powyższego
  • PBKDF2 - jeśli wymagasz FIPS, w przeciwnym wypadku nie ma sensu, bo powyższe są z reguły wydajniejsze i bezpieczniejsze

Na 100% nie używasz nic z poniższych:

  • Szyfrów, bo wtedy jesteś uzależniony od tego by nie wyciekł klucz. Zdecydowanie lepiej jest użyć jakąś one-way function.
  • Generycznych funkcji skrótu, zwłaszcza bez soli. Są one zwyczajnie za szybkie, bo są ograniczone tylko przez moc obliczeniową. Dodatkowo dla wielu popularnych funkcji istnieją olbrzymie tęczowe tablice.
  • MAC, bo to nie jest absolutnie ich zadanie. Oraz mają dokładnie ten sam problem z szybkością co ww. funkcje skrótu.
  • Argon2d bo jest podatny na side-channel (dostęp do pamięci bazujący na tekście jawnym, timing-attack jest możliwy)
3

Z podanej listy: nie używać żadnego. To nie są hashe do takich celów! A bez soli to juz w ogóle.
Do hashowanie haseł bcrypt, PBKDF2, Argon2 będą ok. ABSOLUNIE nie używaj jakiegoś AESa ani innego szyfrowania! Przecież jak ci wycieknie baza to pewnie kod z kluczem też i ktoś sobie je wszystkie odszyfruje.

0

Mam bana za to dostać? LOL, jeżeli ktoś zamyka dom i chowa klucz pod wycieraczkę, to już nie moja wina :D

0

Świetny temat, zupełnie z głowy mi wyleciały funkcje to haszowania haseł dedykowane do tego, nawet nie wpadłem, żeby czegoś na ten temat poszukać. Zamiast użyć np. bcrypta to stworzyłem sobie coś takiego, że do bazy zapisywany jest wynik SHA512(SHA256(sól1)+SHA256(hasło)+SHA256(sól2)) :P

0
lukaszek016 napisał(a):

Świetny temat, zupełnie z głowy mi wyleciały funkcje to haszowania haseł dedykowane do tego, nawet nie wpadłem, żeby czegoś na ten temat poszukać. Zamiast użyć np. bcrypta to stworzyłem sobie coś takiego, że do bazy zapisywany jest wynik SHA512(SHA256(sól1)+SHA256(hasło)+SHA256(sól2)) :P

Takie coś ma sens?

Czy to nie jest to, o czym tu piszą?

https://security.stackexchange.com/questions/25585/is-my-developers-home-brew-password-security-right-or-wrong-and-why

@Shalom

0

@lukaszek016 nie ma i w ogóle jest badzo bardzo bardzo słabe.

  1. SHA256(sól1) i SHA256(sól2) to STAŁE. Jak ktoś ukradnie bazę to ukradnie też te wartości. Ergo równie dobrze mogło by ich nie być...
  2. Efektywnie ktoś musi łamać jedynie SHA256(hasło), a tutaj nawet nie dodałeś soli
0

Podepnę się pod wątek i zadam pytanie dodatkowe: jak generować dobry salt? :)

Co sądzicie o:

  1. Operator uruchamia aplikację i podaje hasło do jakiegoś składziku tajnych rzeczy
  2. Aplikacja otwiera "składzik" korzystając z hasła podanego przez operatora
  3. Aplikacja odczytuje sekretny token o nazwie token1
  4. Aplikacja stara się "zapomnieć" hasło do składzika
  5. Aplikacja generuje salt jako funkcję (login, password, sekretny token)
  6. Aplikacja dla użytkownika generuje hasza "salt + password " i zapisuje, ze wykorzystano token o nazwie token1

Słaby punkt: token1 jest w pamięci.

1

Nie widzę isyotnej przewagi nad zwykłym generowanym saltem.
Salt zależny od hasła to natomiast na pewno słaby punkt
Jesli masz naprawdęsekretny bezpieczny składzik na te tokeny, to oszczędź sobie pracy i zamiast tokenów trzymaj w składziku hasła/(hashe). Profit. :)
Jeśli wyjęty token1 będzie użyty więcej niż raz to możesz roboczo przyjąć, że nie masz soli/jest stała. Czyli kiepsko.

0
jarekr000000 napisał(a):

Nie widzę isyotnej przewagi nad zwykłym generowanym saltem.

Istotna różnica, to to, że taki salt nie byłby zapisywany w bazie razem z hasłem, tylko liczony z tego co poda user + magic value.

Salt zależny od hasła to natomiast na pewno słaby punkt

Jeśli oparty tylko o hasło, to pewnie tak.

Jesli masz naprawdęsekretny bezpieczny składzik na te tokeny, to oszczędź sobie pracy i zamiast tokenów trzymaj w składziku hasła/(hashe). Profit. :)

Jeśli byłby skalowalny, to czemu nie :D Ale miałem na myśli coś typu javowy keystore. Pomijam kwestie wygody i utrzymywania tego ;)

0

Powiedzmy dokładniej : napisz jak robisz funkcję (login, password, sekretny token), a zobaczymy jak to atakować...

0
yarel napisał(a):

Słaby punkt: token1 jest w pamięci.

A przypadkiem jeżeli ktoś ma dostęp do pamięci, to nie masz większych problemów? :P

jarekr000000 napisał(a):

Powiedzmy dokładniej : napisz jak robisz funkcję (login, password, sekretny token), a zobaczymy jak to atakować...

"Wszyscy" robią w ten sposób:

https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/consumer-apis/password-hashing?view=aspnetcore-2.1

https://www.c-sharpcorner.com/article/hashing-in-asp-net-core-2-0/

https://tahirnaushad.com/2017/09/09/hashing-in-asp-net-core-2-0/

Czyli KeyDerivation.Pbkdf2 + HMACSHAXXX

byte[] salt = new byte[128 / 8];

new RNGCryptoServiceProvider().GetBytes(salt);

// derive a 256-bit subkey (use HMACSHA1 with 10,000 iterations)
string hashed = Convert.ToBase64String(KeyDerivation.Pbkdf2(
	password: password,
	salt: salt,
	prf: KeyDerivationPrf.HMACSHA1,
	iterationCount: 10000,
	numBytesRequested: 256 / 8));

Atakuj :P

0
WeiXiao napisał(a):

Słaby punkt: token1 jest w pamięci.

A przypadkiem jeżeli ktoś ma dostęp do pamięci, to nie masz większych problemów? :P

To jest akurat istotny punkt. Przez swap lub jakiś dump można często wymusic zrzut pamięci. Tak się projektuje algorytmy, aby zminimalizowac szkody takiego ataku (hasło jak najkrócej w pamięci). Dlatego np. w javie wszelkie funkcje od security chodzą na tablicy bajtów, a nie na stringach. Tablice bajtów możesz szybko wyczyścić po użyciu (i powinieneś). String (immutable) może się z różnych powodów długo po pamęci panoszyć.

0
jarekr000000 napisał(a):

Powiedzmy dokładniej : napisz jak robisz funkcję (login, password, sekretny token), a zobaczymy jak to atakować...

Nie robię :P Ale gdybym robił to pewnie w coś w ten deseń:

Token[0..255] - wartości od 00..FF  
salt = Token[ password[i] ] + Token[ login[j]  ]
albo 
salt = HASZ(Token[ password[i] ] + Token[ login[j] ])

gdzie i,j przebiegają odpowiednio: i=0..len(password)-1, j=0..len(login)-1

Ewentualnie inna długość tokena i mod 256 w indeksowaniu.

1

Mając w pamięci ten wątek znalazłem filmik o różnicy m. szyfrowaniem a hashowaniem - wersja dla opornych:

1
yarel napisał(a):
Token[0..255] - wartości od 00..FF  
salt = Token[ password[i] ] + Token[ login[j]  ]
albo 
salt = HASZ(Token[ password[i] ] + Token[ login[j] ])

gdzie i,j przebiegają odpowiednio: i=0..len(password)-1, j=0..len(login)-1

Ewentualnie inna długość tokena i mod 256 w indeksowaniu.

Krótko, nie ma problemu z tym, że ten robisz tam proste podstawienie itp. (see nasze komentarze pod postem).
Technicznie i tak założenie jest, że tokeny udaje się zdobyć (bo znowu jeśli umiesz bezpiecznie przechować tokeny to czemu w ten sam sposób nie przechować hashy do hasel :-)).

Więc zakładamy, że wszystko wycieka - atakujący ma algorytm , hashe i te tokeny.

Problem jest, że powstaje ciekawa właściwość
Konta (z hasłami):
arel / qwerty (oczywiście słabe hasło)
yarel / qwert (dużo mniej oczywiste... )

będą miały tą samą sól i będzie można zgadywąć po loginach, gdzie takie szanse są możliwe.

Dramatu nie ma od razu - bo masz różne hasła i hash wyjdzie inny.

Nie mam też pojecia w tej chili pojęcia jak to zaatakować, ale tego typu własności zwykle się mszczą. I z tego co wiem, jest to po prostu słabsze rozwiązanie niż po prostu losowa i zapisana nawet w bazie sól.

EDIT: Już wiem.
Trzeba się było piwka napić, żeby znaleźć dlaczego ten pomysł z saltem zależnym od hasła to naprawdę zły pomysł.
Jeśli sól to funkcja postaci salt = Token[ password[i] ] + Token[ login[j] ] (czy w zasadzie jakakolwiek, gdzie hasło jest inputem, jednym z inputów).
To: albo nie zapisujemy tego salta w bazie, bo przecież chcemy być secure... ale jak wtedy zweryfikowac czy ktoś podał dobre hasło przy logowaniu....? trzeba by mieć plain text tego hasła... Czyli słabo. Inaczej nie odtworzymy soli (nie mając plain textu hasła ) i nie możemy zweryfikować nikogo przy logowaniu. Słaby to system.

W takim razie, jednak wynik takiej funkcji salt - musimy zapisać. Ale wtedy zamiast odwracać hash żeby zgadnąć hasło, to mamy dużo prostszą metodę ataku przez to, że mamy zapisane jak wygląda salt ( który też zależy od hasła !).
W najgorszym razie sprowadza się to przypadku, jakby po prostu nie było soli (w przypadku jeśli : salt = HASZ(Token[ password[i] ] + Token[ login[j] ])).i8

0

Czy to, co tu piszą, ma sens?

https://security.stackexchange.com/questions/211/how-to-securely-hash-passwords

Wnoszę że ma, po fakcie że jest to 3. najwyżej zupvoteovane pytanie na tej stronie. Więc gdyby nie było, ktoś by się już zorientował

1 użytkowników online, w tym zalogowanych: 0, gości: 1