Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Kilka znaków zamiast całego hasła - jak to działa?
Forum PHP.pl > Forum > PHP
Stron: 1, 2
NetBeans
Cześć.
Pewnie większość z Was kojarzy metody logowania na stronach banków. Jest to wykonane w ten sposób, że musimy podać tylko kilka znaków naszego hasła (reszta jest zablokowana, tak jakby już były wpisane). Zastanawiam się w jaki sposób to działa. Zakładam, że hasła są hashowane, więc w jaki sposób porónywane są ciągi, skoro są niekompletne. Nie jest chyba możliwe, że system wie jakie znaki hasła mamy pod daną cyferką (widoczne na obrazku) i uzupełnia ciąg do porównania z hashem. Do tego "szare" pola są generowane losowo. Interesuje mnie zasada działania, nie proszę o żaden gotowy kod etc.
Pozdrawiam. smile.gif

Wspomniany obrazek:
b4rt3kk
Rzeczywiście, hasło na pewno nie jest przechowywane w formie jawnej i na pewno nie jest to jeden hash, ale nic nie stoi na przeszkodzie, by było to np. 10 hash-ów, każdy odpowiedzialny za zakodowanie 1 znaku.
NetBeans
Tak, ale hashe dla każdego znaku z tablicy ASCII (a nawet dla wielu prostych słów) są dostępne w Google dla każdej funkcji hashującej. Nie byłboby to bezpieczne, nieprawdaż?
pyro
Hasło: przykładowo X znaków

czyli X wpisów do tabeli user_password_chars_hashes (z relacją do usera), każdy znak oddzielnie hashowany jednostronie (np. SHA-256).

Nie takie trudne jak się wydaje.
adamantd
Ciekawe smile.gif
A może tak.
1. rejestrujesz się do systemu bankowego i wymyślasz sobie hasło
2. system rozbija je na literki, koduje każdą z nich jednostronnie
3. zapisuje do bazy w postaci zakodowanaPojedynczaLiterka|zakodowanaDrugaLiterka|zakodowanaTrzeciaLiterka|itd itd
4. chcesz się zalogować, system wyciąga z bazy twoje hasło i rozbija na tablicę i przedstawia Ci losowo np 4, 6, 9 pole do uzupełnienia a pozostałe pokazuje że są uzupełnione (w rzeczywistości nie są tylko tak wygląda, żeby łatwiej było Ci policzyć którą masz wpisać)
5. system koduje te literki i porównuje z poszczególnymi wartościami z tablicy
b4rt3kk
Cytat(NetBeans @ 13.07.2013, 12:56:41 ) *
Tak, ale hashe dla każdego znaku z tablicy ASCII (a nawet dla wielu prostych słów) są dostępne w Google dla każdej funkcji hashującej. Nie byłboby to bezpieczne, nieprawdaż?


Każdy znak można odpowiednio "posolić".
NetBeans
Faktycznie, jedynie soląc hashe znaków byłoby to w miarę bezpieczne. Inaczej możnaby stworzyć mini tablicę tęczową z hashami dla każdego znaku ASCII, a następnie przelecieć dany hash. Wtedy takie zabezpieczenie byłoby bez sensu. No cóż, chyba doszliśmy (a właście doszliście) do rozwiązania. Jeżeli ktoś ma jeszcze inny pomysł to chętnie poczytam.
gitbejbe
tak jak piszecie powyżej.

Systemy bankowe mają tą przewagę, że wszystkie informacje o klientach nie są jawne. To nie forum gdzie widać kto ma jaki nick, kiedy się zarejestrował itd.... Nie ma żadnych danych o klientach co daje duże pole manewru do bezpiecznego hasowania haseł. Też uważam, że takie hasło poprostu rozbija się na pojedyncze znaki i odpowiednio soli. Solą może być wszystko, więc nie będę wymyślał jakiś przykładów ale taki rodzaj sprawdzania hasła dla zwykłych witryn jest zbędny...
pyro
Warto dodać, że sól powinna być wyłącznie zahardcodowana w skrypcie, a nie w bazie danych tak jak np. to się podaje w każdym wierszu userów w ich tabeli.
drPayton
Cytat(pyro @ 16.07.2013, 11:15:14 ) *
Warto dodać, że sól powinna być wyłącznie zahardcodowana w skrypcie, a nie w bazie danych tak jak np. to się podaje w każdym wierszu userów w ich tabeli.


Chyba, że każde hasło (czy ogólnie: każdy hashowany string) ma osobną sól. Wówczas nie ma innej opcji jak zapisywanie ich w bazie a potencjalny "kradziej" bazy danych, nie mając kodu i tak nie wie jak sól jest używana... (a jak kod ma to i hardcodowaną w nim sól wink.gif
pyro
Cytat(drPayton @ 16.07.2013, 21:55:04 ) *
Chyba, że każde hasło (czy ogólnie: każdy hashowany string) ma osobną sól. Wówczas nie ma innej opcji jak zapisywanie ich w bazie a potencjalny "kradziej" bazy danych, nie mając kodu i tak nie wie jak sól jest używana... (a jak kod ma to i hardcodowaną w nim sól wink.gif

No tak... bo komu by się chciało poświęcić setki godzin aby sprawdzić, czy litera jest hashowana tak:

'a'.'UltraSol'

Czy tak:

'UltraSol'.'a'

Proszę o przemyślenie sprawy przed napisaniem kolejnego postu tego typu.
Sephirus
Włączę się bo widzę pewną potencjalną lukę. Przy takich założeniach gdzie mamy pojedyncze literki hashowane oddzielnie dość łatwo jest wyciągnąć hasła wszystkich userów.

Założenia:
1. Literki są hashowane i solone tym samym ciągiem (ciąg na sztywno w kodzie)
2. Na wstępie mamy bazę powiedzmy 1000 userów z różnymi hasłami - bierzemy wszystkie możliwości hashu literek (unikalne - maks liczba = liczbie znaków w alfabecie hasła)
3. Dla każdej możliwości bruteforcem jedziemy i szukamy literki tworząc hashe ze znaną solą,
4. Mamy tablice (hash => literka) - prosty skrypt i mamy tysiąc haseł smile.gif

Czas realizacji po włamie na serwer i ściągnięciu danych wg mnie: manualnie: ~1h, automatycznie (skrypt): 5minut?

Warto zauważyć że jak raz się skapniemy jak dodawany jest do literki salt to potem już jest błyskawicznie...

Więc taka opcja odpada na bank (chyba, że o czymś zapomniałem).

Wynika mi z tego, że każda literka powinna mieć różne sole, bądź rózni userzy różne sole. Wydaje mi się jednak, że to jedynie nieco spowolni proces bo sól danego usera musi być gdzieś zapisana/generowana a z tego wynika, że dla konkretnego gościa musimy jedynie przelecieć wszystkie literki z tą solą i i tak odzyskać hasło. Można napisać skrypt który ogarnie to w dość szybkim czasie dla każdego z userów osobno.

Co wy na to? Czy o czymś zapominam czy to jednak totalna bzdura?

Dla porównania bruteforce na normalnej długości haśle, nawet posiadając sól już nie potrwa tak krótko...
pyro
Cześć.

Mając trochę doświadczenie w temacie raczej bzdura. No chyba, że ta sól to coś w stylu "abcd".

Jak Ty sobie wyobrażasz złamanie hashu w stylu:

'a'.'diuu5778912UIDFH3279&^@^$CFHSHNSHDFMsif375*&@(%%Y^|YHF998@*($fhhfjLL'

W ciągu ileś minut / godzin? Jak dla mnie można z takim czymś spokojnie spać nawet do końca życia. Nawet jak natrafisz na kolizję to Ci nic nie da poza odkodowaniem jednej literki.

Co do tęczowych tablic - mam wrażenie, że po prostu nie wiesz co to jest wink.gif .
b4rt3kk
Jakby solą był np. login użytkownika (lub kilka znaków z loginu, np. pierwszy, ostatni i 3) + unikalny hash jeszcze raz zahashowane razem i dopiero użyte jako sól to nie ma takiej opcji żebyś brute forcem odkodował literka po literce. No chyba, że znałbyś metodę kodowania, czyli musiałbyś mieć dostęp do skryptów.
Sephirus
@pyro

Wyobraź sobie, że wyobrażam smile.gif (zauważ, że mówię tu o włamania na FTP + DB a nie samym DB - wówczas masz rację)

salt = xxx... (znany)
hash = yyy...
metoda hashowania znana (załóżmy) hash = f([literka].salt);

mam Ci napisać FORa, który to szybko zgadnie literkę? smile.gif Ile będzie miał iteracji... hmm.. nie wiem ale pewnie ~100 max smile.gif

Dalej... mam już "rozszyfrowana" literkę x, potem robie to samo dla y, z, ....

Mam wszystkie literki => mam wszystkie hasła - proste?

To wszystko w założeniu istnienia jednej soli.

Dla różnych soli proces wcale nie jest bardziej skomplikowany.

Nic nie pisałem o tęczowych tablicach - są tu zbędne - jesli naprawdę "masz trochę doświadczenia w temacie" to wyjechanie z nimi oznacza jedynie, że nie rozumiesz co napisałem smile.gif

@up

Zgadzam się - ale to właśnie zakładam a wbrew pozorom trzeba to mieć na uwadzę, że ktoś może się włamać na serwer (co mu też daje dostęp do DB). W przypadku zwykłych haseł liczba kombinacji nawet znając SALT i układ jest ogromna. Dla jednej literki liczba kombinacji jest max 3 cyfrowa (tak na prawdę 2 cyfrowa w praktyce)
pyro
@Sephirus, według Twojego toku myślenia jak włamywacz znajdzie nawet reflected XSS to ma kontrolę nad całym serwerem.

Jeżeli ktoś się włamie do bazy danych (SQL Injection, weak password, inne.) i ma tam też wszystkie sole, to w ogóle po jaką cholerę one miały by być? A jak się włamie do bazy danych, a sól jest długa i zahardcodowana w skrypcie, to te wszystkie hashe dla niego raczej bezwartościowe ciągi znaków i jeżeli nie znajdzie sposobu na dostanie się do plików, to jest bezsilny. Widzisz różnicę?
sowiq
Koledzy, wtrącę się i ja, bo kiedyś myślałem o takim rozwiązaniu. Wybaczcie, ale trochę kupy nie trzyma się Wasze rozumowanie. Najpierw napiszę dlaczego, a później opiszę moje rozumowanie.

1. Hashowanie pojedynczych znaków

1.a. Wspólna sól trzymana w kodzie.
Przypadek trywialny, bo sami sobie robimy szyfr słownikowy. Każdemu znakowi będzie w bazie odpowiadał jeden, taki sam ciąg. Mało tego - po znalezieniu soli dla jednego znaku znamy ją globalnie. Czas złamania - kilka minut na znak w zależności od długości soli. Ewentualnie można polecieć algorytmem statystycznym, jak to robili już w czasie II wojny światowej wink.gif

1.b. Każdy znak solony inną solą.
W tym przypadku nie ma innej opcji jak trzymanie każdej soli w bazie. Przypadek jeszcze łatwiejszy niż poprzedni, bo niewiadomą jest już tylko szukany znak. Ile milisekund potrzebowałby w miarę szybki komputer na wygenerowanie n hashy (n - liczba dostępnych znaków)?

1.c. Sól generowana dynamicznie w kodzie dla każdego usera.
Rozwiązanie najlepsze z tych 3. Ale domyślam się, że po złamaniu pierwszych 1000 haseł bez większego problemu można znaleźć klucz, który określa w jaki sposób generowana jest ta sól. Bo oczywiście nie może to być losowanie, bo za każdym razem dla danego usera musi być wygenerowana ta sama sól.


2. Moje rozumowanie

2.a Generowanie n kombinacji
Jak dla mnie najbezpieczniejszym rozwiązaniem byłoby wygenerowanie n kombinacji dla danego hasła. Załóżmy dla uproszczenia, że hasło składa się z 5 znaków, a user musi wpisać co najmniej 3. Daje to 26 kombinacji (poprawcie mnie jeśli się mylę). Zapisujemy każdą z nich w bazie jako posolony hash. Przy każdym rekordzie zapisujemy które znaki są w nim zawarte i zapisujemy też sól. Przed logowaniem system wybiera z bazy opcję hasła (które znaki trzeba wpisać), a później hashuje hasło i porównuje z informacją w bazie, podobnie jak przy "normalnym" logowaniu.
Wady:
- przy dłuższych hasłach hashy będzie dosyć sporo
- przy algorytmach lepszych niż md5/sha1, czas generowania kombinacji może być dosyć długi (kilka/naście sekund?)
- trochę skomplikowana implementacja generowania kombinacji
Zalety:
- kombinacje generowane tylko podczas zakładania konta i zmiany hasła
- IMO całkiem bezpieczne rozwiązanie
pyro
Cytat(sowiq @ 17.07.2013, 09:23:57 ) *
Koledzy, wtrącę się i ja, bo kiedyś myślałem o takim rozwiązaniu. Wybaczcie, ale trochę kupy nie trzyma się Wasze rozumowanie. Najpierw napiszę dlaczego, a później opiszę moje rozumowanie.

1. Hashowanie pojedynczych znaków

1.a. Wspólna sól trzymana w kodzie.
Przypadek trywialny, bo sami robimy szyfr słownikowy. Każdemu znakowi będzie w bazie odpowiadał jeden, taki sam ciąg. Czas złamania - kilka minut na znak w zależności od długości soli. Ewentualnie można polecieć algorytmem statystycznym, jak to robili już w czasie II wojny światowej wink.gif


To jest mój hash: e152c000118ddbc4b372c6e1d8289696662de535993269e715348f02f9b4f238

Powiem Ci w jak on jest zaszyfrowany: SHA256
Ba... powiem Ci nawet z której strony jest literka: na początku.
Mega Ba!... powiem Ci nawet ile znaków ma sól: 76
Jeżeli uda Ci się to złamać kiedykolwiek, to obiecuję Ci, że uczynię nas obu bogatymi. A jeżeli tak jak to mówisz dla Ciebie kwestia kilka minut to ohohho!

Czas start!
Sephirus
@pyro - nie mam zamiaru się z Tobą kłócić o to czy da się włamać na serwer (i jak) czy się nie da - to jest OT. Podałem w moim rozumowaniu bardzo mocną lukę takiego kodowania "literek" jesli ktoś ma dostęp do serwera - bo ma wtedy dostęp do wszystkiego co mu jest potrzebne aby rozkodować wszystkie hasła.

Więc przeczytaj to uważnie i odpowiedz mi: Mam dostęp całkowity do serwera i DB - czy moje rozumowanie jest wówczas poprawne czy nie? (nie mam zamiaru tu wmawiać nikomu, że gdybym miał sam dostęp do bazy do tym odhashował wszystkie hasła - a Ty mi to wmawiasz.)

Nie mówię tu o żadnym XSS tylko full dostępie - musisz sobie przypomnieć, że wyciek danych to nie koniecznie potocznie zwany "hakier" ale na przykład niedopłacany programista, który ma dostęp do serwera, bądź jakiś kolega, który pochwali się jaki to wspaniały system zrobili hashowania literek itd.

Sam mam dostępy do różnych baz z masą kont użytkowników. Sam wiem jakich metod uzywamy do przechowywania haseł w bazie. Ta wiedza daje mi tyle, że nigdy bym się nie pokwapił na próbę ich rozkodowania nawet mając full dostęp (jedyne co mógłbym zrobić to przy rejesteacji wysylać mail do siebie z jawnym hasłem tongue.gif ). W tym jednak przypadku wydaje mi się dość prostę odszyfrowanie tego wszystkiego - a ja (może się mylę?) widze to jako duże zagrożenie... ale może polityka bezpieczeństwa wewnętrznego jest nieistotna tongue.gif

sowiq
Cytat(pyro @ 17.07.2013, 09:31:43 ) *
Czas start!

Zwróć szczególną uwagę na to:
Cytat
sami sobie robimy szyfr słownikowy [...] można polecieć algorytmem statystycznym, jak to robili już w czasie II wojny światowej


[edit]
Mało tego. Przypadek może trochę z dupy, ale wyobraź sobie, że "atakujący" sam ma konto w serwisie, z którego pochodzi baza. Jego konto ma 20-znakowe hasło. I co? I 20 znaków z naszego słownika leci "w pizdu" wink.gif
pyro
@Sephirus, chyba należy doprecyzować o jakim przypadku to mówimy: jak ktoś ma dostęp i kontrolę nad całym serwerem, to po co miałby łamać jakiekolwiek hashe? Po pierwsze włamywacze głównie włamują się na konkretny serwer bo mają konkretnie w nim jakiś cel. W mniejszości istnieją przypadki, gdzie wykradane są bazy danych, bo np. chcą sprawdzić czy dani użytkownicy nie używają takich samych haseł gdzieś indziej. Ale skoro ma kontrolę nad całym serwerem to dużo prościej i szybciej po prostu napisać skrypt, który loguje wpisywane przez użytkownika hasła gdzieś tam. Dlatego wydawało mi się to dość oczywiste, że mówimy tu o przypadku, gdzie ktoś wykradł sobie nawet całą bazę danych.


Cytat
Zwróć szczególną uwagę na to:


Cześć. Nie widzę zastosowania... w temacie w ogóle. Nie, nie musisz mi podsyłać linków, wiem o co chodzi. Nie ironizując chętnie się dowiem co masz na myśli. Rozwiń wypowiedź najlepiej z jakimś przykładem.

Cytat
Mało tego. Przypadek może trochę z dupy, ale wyobraź sobie, że \\\"atakujący\\\" sam ma konto w serwisie, z którego pochodzi baza. Jego konto ma 20-znakowe hasło. I co? I 20 znaków z naszego słownika leci \\\"w pizdu\\\" wink.gif


Chcesz mogę podać Ci nawet co to za literka w moim hashu (czyli tak jak atakujący zna swoje hasło). Odkodujesz wtedy cały ciąg znając dokładnie co to za hash i o jakiej długości? Nie sądzę wink.gif
Sephirus
@up

Masz rację, że mając taki dostęp można zrobić "wszystko". Ale jeśli pracujesz na bazie która ma już X klientów to ich haseł nie odzyskasz (chyba że będą je zmieniali i wrzucisz tam "swój skrypt"). Wiele przypadków wycieku informacji (jeśli nie większość - nawet w PL) wynikała albo ze złych zamiarów samych pracowników albo z ich głupoty (zapisanie gdzieś hasła do FTP, używanie programu XXX do FTP/SSH który wysyła sobie gdzieś hasło itd. itp. Tak czy owak taki dostęp mógłbyć z wewnątrz lub niechcący z zewnątrz. Jeśli byłby z zewnątrz to w takim układzie kodowania haseł wystarczy "skopiować" to co nas interesuje zostawiając po sobie tylko parę linijek w logu... Wrzucanie swoich skryptów jest już bardziej ryzykowne - bo lepiej wykrywalne - chociażby mechanizm wersjonowania krzyknie że jest jakiś konflikt. Więc tutaj poszła by zmiana dostępów i usunięcie tego kodu.

Moje zdanie jest takie, że dla mnie jest to proste do odkodowania. Jeśli tak jest to jest potencjalnie możliwy wyciek wewnętrzny. Dla mnie to nie do zaakceptowania. Toteż uważam, że muszą to robić nieco inaczej albo nikt nie pomyślał o tym co napisałem (w co bardzo wątpie). Innymi słowy - te podawanie literek wybranych z haseł musi być nieco bardziej zamotane IMO.

W innych aspektach w pełni się z Tobą zgadzam bo masz rację. Mam nieco bzika na punkcie bezp. wew. stąd takie czepianie się wink.gif

Popieram Cię także, że nie da się z "e152c000118ddbc4b372c6e1d8289696662de535993269e715348f02f9b4f238" wyciągnać literki jaką tam wrzuciłeś zbyt szybko (w tym roku, życiu). Metody statystyczne odpadają - opierają się one naogół na danym jezyku - więc zakładają jakieś konkretne używanie danych literek co dla losowej soli jest bzdurą. Metody słownikowe też odpadają.
sowiq
@pyro, rzeczy, o których pisałem, tyczą się kodowania pojedynczych znaków globalną solą. Znaczy to, że każda literka 'a' będzie w bazie zapisana za pomocą identycznego hasha. Tak samo wszystkie pozostałe znaki. W ten sposób zamiast jednostronnego hashowania tworzysz sobie słownik:
a => hash1
b => hash2
...

Atak statystyczny co prawda ma zastosowanie do długich tekstów, ale zakładam, że tutaj też dałby radę. Mało tego - możesz na pałę próbować przyporządkować poszczególne litery hashom i sprawdzać, czy uda Ci się zalogować na działającym serwisie. Wcale nie musisz do tego celu używać bruteforce. A jak napisałem wcześniej - jeśli masz konto z 20-znakowym hasłem, to automatycznie znasz 20 znaków ze zdobytego słownika.

Jeśli bardzo chcesz linka, to proszę: http://pl.wikipedia.org/wiki/Atak_statystyczny Sorry, źle przeczytałem Twojego posta.
buliq
Algorytm może tworzyć zasolony (każdy znak, inna sól) hash znaku po czym ucinać go w pewnym momencie i łączyć w pojedynczy string. Życzę powodzenia w zgadywaniu, w którym miejscu jest jeszcze stary poprzedni znak, a w którym już nowy. Hashe znaków mogę mieć też różną długość.
sowiq
Ucinanie hasha to osłabianie szyfrowania - większa możliwość kolizji.

Cytat(buliq @ 17.07.2013, 09:59:25 ) *
Życzę powodzenia w zgadywaniu, w którym miejscu jest jeszcze stary poprzedni znak, a w którym już nowy. Hashe znaków mogę mieć też różną długość.

Życzę powodzenia Twojemu skryptowi logującemu wink.gif

Zaciemnianie != podnoszenie bezpieczeństwa.
drPayton
Cytat(pyro @ 17.07.2013, 08:12:25 ) *
No tak... bo komu by się chciało poświęcić setki godzin aby sprawdzić, czy litera jest hashowana tak:

'a'.'UltraSol'

Czy tak:

'UltraSol'.'a'

Proszę o przemyślenie sprawy przed napisaniem kolejnego postu tego typu.


Pomyśl, ale Ty. Dlaczego uważasz, że tylko takie dwie możliwości są?

Aczkolwiek oczywiście faktem jest, że nie jest to rozwiązanie najlepsze. No ale tego też nie pisałem snitch.gif
buliq
Cytat(sowiq @ 17.07.2013, 10:07:36 ) *
Ucinanie hasha to osłabianie szyfrowania - większa możliwość kolizji.


Życzę powodzenia Twojemu skryptowi logującemu wink.gif

Zaciemnianie != podnoszenie bezpieczeństwa.


Fakt, nie zwróciłem uwagi na możliwe kolizje.

Może tworzą gotowe hashe dla konkretnych zestawów?
Albo stworzyli własną metodę kodującą, nie hash'ującą ?
pyro
Cytat(sowiq @ 17.07.2013, 09:50:37 ) *
Atak statystyczny co prawda ma zastosowanie do długich tekstów, ale zakładam, że tutaj też dałby radę. Mało tego - możesz na pałę próbować przyporządkować poszczególne litery hashom i sprawdzać, czy uda Ci się zalogować na działającym serwisie. Wcale nie musisz do tego celu używać bruteforce. A jak napisałem wcześniej - jeśli masz konto z 20-znakowym hasłem, to automatycznie znasz 20 znaków ze zdobytego słownika.


Cześć. Jeżeli jest sobie "serwisik", gdzie jest wolna rejestracja, da się robić multikonta albo przynajmniej dawać długie hasła to rzeczywiście miałoby sens. Masz rację. Ale biorąc pod uwagę rzeczywistość i gdzie tego typu logowania są stosowane mogłoby być ciężko wink.gif .

// EDIT

Poza tym wtedy jakiekolwiek solenie ani nawet hashowanie nie miałoby sensu, bo dla każdej literki byś znał jej hash. Sól niepotrzebna (nawet jak unikalna dla każdej literki). Chyba, że generowanie na podstawie zewnętrznych danych związanych z czymś tam np. loginem użytkownika.


Cytat(drPayton @ 17.07.2013, 10:19:18 ) *
Pomyśl, ale Ty. Dlaczego uważasz, że tylko takie dwie możliwości są?


A jakie są inne możliwości wstawienia soli dla jednej literki jak nie przed i jak nie po? Przykładowo pomiędzy brzuszkiem literki "b", a jej górnym ogonkiem baaasmiley.gif ?
sowiq
Cytat(pyro @ 17.07.2013, 10:43:09 ) *
Cześć. Jeżeli jest sobie "serwisik", gdzie jest wolna rejestracja, da się robić multikonta albo przynajmniej dawać długie hasła to rzeczywiście miałoby sens. Masz rację. Ale biorąc pod uwagę rzeczywistość i gdzie tego typu logowania są stosowane mogłoby być ciężko wink.gif

Nie zgodzę się. Załóżmy, że serwis pozwala na hasło o długości max 20 znaków (nie widzę powodu, żeby miało to być mniej). Właśnie takie sobie tworzysz. Znasz już 20 pozycji z x-znakowego "alfabetu". Szukasz w bazie n-znakowych haseł, w którym n-1 znaków pochodzi ze znanych pozycji alfabetu. Wchodzisz na stronę logowania i max x-20 razy próbujesz się zalogować. Jak Ci się uda - znasz kolejny znak alfabetu. Powtarzasz czynność tyle razy, żeby poznać cały alfabet.

Zalety takiego podejścia? Możesz mieć 1k-znakową sól i nie wiadomo jaki algorytm hashowania. Atakującego to nie obchodzi, bo słownik może sobie stworzyć niezależnie od tego.

Rozumiesz teraz moje podejście?

[edit]
Cytat
Poza tym wtedy jakiekolwiek solenie ani nawet hashowanie nie miałoby sensu, bo dla każdej literki byś znał jej hash. Sól niepotrzebna (nawet jak unikalna dla każdej literki). Chyba, że generowanie na podstawie zewnętrznych danych związanych z czymś tam np. loginem użytkownika.

No właśnie tak napisałem w moim pierwszym poście tutaj. Jeśli Ci umknął, to zajrzyj [KLIK].
pyro
Przecież mówimy dokładnie o tym samym. snitch.gif

Cytat(sowiq @ 17.07.2013, 10:52:25 ) *
No właśnie tak napisałem w moim pierwszym poście tutaj. Jeśli Ci umknął, to zajrzyj [KLIK].


Widocznie umknął.

// EDIT

Mi tylko chodziło o to zastrzeżenie:

Cytat
Ale biorąc pod uwagę rzeczywistość i gdzie tego typu logowania są stosowane mogłoby być ciężko wink.gif .
redeemer
Pozwólcie, że wtrącę moje trzy grosze na temat "solenia".

Oddzielna sól dla każdego użytkownika trzymana w bazie danych ma utrudnić atak gdzie potencjalny włamywacz będzie chciał poznać hasła wszystkich użytkowników. Nie utrudni to łamania haseł jednostkowo wybranych użytkowników, ale bardzo znacząco wydłuży czas złamania wszystkich haseł w bazie w przypadku wycieku.

Więc, jeśli chodzi o solenie to dlaczego nie zastosować równocześnie stałej soli (zahardkodowanej, z konfiga, itd.) i soli zmiennej dla każdego użytkownika z bazy danych?

@pyro: możliwości wstawienia soli zależą tylko i wyłącznie od finezji programisty. Możemy taką sól wcześniej zxorować, rozdzielić na pół i doklejać z obu stron, odwrócić itd.
pyro
Cytat(redeemer @ 17.07.2013, 10:56:42 ) *
@pyro: możliwości wstawienia soli zależą tylko i wyłącznie od finezji programisty. Możemy taką sól wcześniej zxorować, rozdzielić na pół i doklejać z obu stron, odwrócić itd.


@redeemer, może nie rozumiem o co Ci chodzi, ale:

  1. // Przykładowo:
  2. $salt = substr(sha1(md5('jdjkdfs738278527&*@#&*%sdldl')), 0, 20);


to dokładnie to samo co:

  1. $salt = 'ff9d69c88cbb998f0983';
redeemer
@pyro: chodziło mi o to, że ktoś wcześniej napisał, że mając daną sól (z bazy) bez dostępu do kodu źródłowego i tak nie wiemy jak jest wstawiana podczas hashowania, natomiast Ty chyba uważasz, że są tylko dwie opcje: doklejenie jej na początku i doklejenie jej na końcu. Cytuje:
Cytat
No tak... bo komu by się chciało poświęcić setki godzin aby sprawdzić, czy litera jest hashowana tak:

'a'.'UltraSol'

Czy tak:

'UltraSol'.'a'
pyro
Sorry miałem na myśli "przed i po", ale w przykładzie rzeczywiście nie dopisałem jednego przypadku.

Mimo to te xorowanie itp. o czym pisałeś dalej nie ma sensu, bo to po prostu tworzenie soli, a nie kodowanie soli.
gitbejbe
nie wiem nad czym się tutaj rozczulać. Dobrze przemyślane hashowanie i solenie daje 100% gwarancje na to, ze nikt tego hasła nie odgadnie bez dostępu do kodu źródłowego. Specjalnie napisałem 100% bo na tyle samo procent jestem pewien, że nikt z was by tego nie dokonał.

Mocnieszy mieszacz- np sha256 czy sha512, losowy token dla każdego konta, swój wymyślony stały hash i ewentualna zabawa z zamianą miejsc w ciągu i jest gitara.
sowiq
@gitbejbe, przeczytałeś wątek? Tu nie chodzi o tak trywialną rzecz jak solenie i hashowanie haseł, tylko oddzielne hashowanie pojedynczych znaków hasła, żeby móc je zweryfikować po wpisaniu wybranych liter. W moim pierwszym poście w tym wątku, w punkcie 1. napisałem o wadach stałej soli oraz o wadach losowej soli trzymanej w bazie.
drPayton
Cytat(pyro @ 17.07.2013, 10:43:09 ) *
(...)
A jakie są inne możliwości wstawienia soli dla jednej literki jak nie przed i jak nie po? Przykładowo pomiędzy brzuszkiem literki "b", a jej górnym ogonkiem baaasmiley.gif ?

A, no przy jednej literce to oczywiście. No i w sumie tego dotyczy temat, na usprawiedliwienie mam to, że trochę zboczył z głównego nurtu wink.gif


Cytat(redeemer @ 17.07.2013, 10:56:42 ) *
(...)
Więc, jeśli chodzi o solenie to dlaczego nie zastosować równocześnie stałej soli (zahardkodowanej, z konfiga, itd.) i soli zmiennej dla każdego użytkownika z bazy danych?
(...)

Yep, dokładnie tak imho powinno być to robione. Oczywiście zysk nie jest wielki (zabezpieczamy się przed wyciekiem *tylko* bazy danych lub *tylko* kodu) ale dobre i to, skoro koszt jest w zasadzie zerowy.
gitbejbe
@sowiq

tak przeczytałem, Twój post również. Stwierdzenie w pkt.1b, że losowy token dla każdego hasła jest jeszcze łatwiejszy do złamania od stałego, sparaliżowało mi chęć odpisania na to do końca dnia. Co do Twojego pomysłu w pkt 2a, nie wiem, nie rozumiem, czytam któryś raz i jedyne czego jestem pewien to to, że sam wymieniłeś więcej wad niż zalet takiego rozwiązania ; )

Jak dla mnie, najprościej i najbezpieczniej jest dla każdego znaku w haśle zrobić losowy token, przemieszać go ze stałym tokenem (+ jakieś inne dowolne stałe, np data założenia konta - ba,można zrobic i tak, że dla znaku 1 bedzie to data rejestracji, dla 2 będzie to login, dla 3 jeszcze coś innego). dodatkowo wszystkie te zaszyfrowane znaki połączyć jako całość i znowu przemieszać. Przy logowaniu - 3 nieudane próby i captcha po 10 próbach ban. Wątpie aby autor wątku pisał system bankowy. Jeśli chce mieć niespotykane logowanie to fajnie, ale nie popadajmy w paranoje. To w zupełności wystarczy
sowiq
@gitbejbe,
Na początku zaznaczę dla pewności, że pisałem o zapisywaniu każdej litery hasła oddzielnie, jako osobny hash.

Cytat(gitbejbe @ 18.07.2013, 07:33:51 ) *
Stwierdzenie w pkt.1b, że losowy token dla każdego hasła jest jeszcze łatwiejszy do złamania od stałego, sparaliżowało mi chęć odpisania na to do końca dnia

Bardzo chętnie dowiem się dlaczego. Jak dla mnie, jeśli token jest losowy i zapisany w bazie (nie generowany z niczego - ten przypadek opisałem w punkcie 1.c), to masz wręcz trywialną sytuację. Do sprawdzenia wszystkie jednoznakowe możliwości dla jednego hasha. Na standardowej klawiaturze możesz wprowadzić 98 znaków, więc na złamanie każdego hasha potrzeba max 98 prób. IMO średnia będzie oscylowała w okolicach 50.
Jeśli coś opisałem nielogicznie/niejasno to bardzo chętnie wyjaśnię Ci mój punk widzenia.

Cytat(gitbejbe @ 18.07.2013, 07:33:51 ) *
Co do Twojego pomysłu w pkt 2a, nie wiem, nie rozumiem, czytam któryś raz i jedyne czego jestem pewien to to, że sam wymieniłeś więcej wad niż zalet takiego rozwiązania ; )

Opisałem to trochę dokładniej tutaj: http://forum.php.pl/index.php?s=&showt...t&p=1056210 Sorry, źle przeczytałem.
Jeśli bierzesz pod uwagę liczbę wad i zalet, a nie zwracasz uwagi jakie one są, to sorry. Wady to skomplikowana implementacja i czas generowania, a zalety to (przynajmniej moim zdaniem) bezpieczeństwo. Jeśli komuś bardzo zależy na bezpieczeństwie, to ta zaleta przebija wszystkie wady. Czaisz?

Wytłumaczę to na przykładzie.
Załóżmy, że masz 5-znakowe hasło: abcde
Załóżmy, że musisz wpisać co najmniej 3 znaki hasła przy logowaniu. Wobec tego będą takie kombinacje ciągu przychodzącego od usera:
Kod
1. abcde
2. _bcde
3. a_cde
4. ab_de
5. abc_e
6. abcd_
7. __cde
8. _b_de
8. _bc_e
...
26. abc__

Dla każdej z takich kombinacji tworzysz w bazie hash (oczywiście dla 20-znakowego hasła, z którego musisz wpisać co najmniej 10 znaków, kombinacje nie będą tak trywialne, ale też będzie ich więcej). Dzięki temu złamać pojedynczy hash nie będzie tak łatwo (duża ilość znaków szukanego ciągu), każdy hash będzie miał swoją losową sól zapisaną w bazie. O wadach i zaletach pisałem już wcześniej.

Cytat(gitbejbe @ 18.07.2013, 07:33:51 ) *
Jak dla mnie, najprościej i najbezpieczniej jest dla każdego znaku w haśle zrobić losowy token, przemieszać go ze stałym tokenem (+ jakieś inne dowolne stałe, np data założenia konta - ba,można zrobic i tak, że dla znaku 1 bedzie to data rejestracji, dla 2 będzie to login, dla 3 jeszcze coś innego)

To jest metoda, którą opisałem w punkcie 1.c.

Cytat(gitbejbe @ 18.07.2013, 07:33:51 ) *
dodatkowo wszystkie te zaszyfrowane znaki połączyć jako całość i znowu przemieszać.

Tutaj rozwaliłeś mnie po raz pierwszy. Pomieszaj, pomieszaj i poproś swój skrypt logujący, żeby później to magicznie odmieszał i sprawdził poprawność wpisanych literek. Tak jak pisałem już wcześniej - zaciemnianie != poprawa bezpieczeństwa.

Cytat(gitbejbe @ 18.07.2013, 07:33:51 ) *
Wątpie aby autor wątku pisał system bankowy. Jeśli chce mieć niespotykane logowanie to fajnie, ale nie popadajmy w paranoje. To w zupełności wystarczy

Ale to nie ma nic do rzeczy. Dyskutujemy tutaj na temat jak najbezpieczniej rozwiązać problem. Może ktoś z nas w przyszłości będzie robił podobne logowanie, gdzie nacisk będzie położony na bezpieczeństwo i będzie musiał zmierzyć się z tym?

Cytat(gitbejbe @ 18.07.2013, 07:33:51 ) *
Przy logowaniu - 3 nieudane próby i captcha po 10 próbach ban.

Najlepsze zostawiłem sobie na koniec. Wyjaśnij mi, proszę, co ma captcha i ban bo łamania haseł w wykradzionej bazie danych, a stawiam browara.
NetBeans
Nie piszę ani systemu bankowego, ani nie mam zamiaru stosować takiej metody autoryzacji. Byłem po prostu ciekaw jak można taki system rozwiązać. Przy okazji udało mi się wywiązać bardzo ciekawą dyskusję. snitch.gif
redeemer
@pyro: Podałem tylko przykład, że pobrana sól z bazy wcale nie musi być doklejana tylko na początku lub na końcu. Zresztą takie "zabawy z solą" w przypadku kodu z zamkniętym źródłem to przykład security by obscurity, a jak już pisał w tym wątku sowiq, jest to nie najlepszy pomysł.

Żeby nie offtopować: http://www.smartarchitects.co.uk/news/9/15...ords---How.html
gitbejbe
Cytat
Bardzo chętnie dowiem się dlaczego


nadal nie wiem co jest w tym prostszego od jednego globalnego tokena ?

Cytat
Wytłumaczę to na przykładzie.
Załóżmy, że masz 5-znakowe hasło: abcde


No dobra, ktoś wykradł bazę userów ale nie zna logiki działania algorytmu szyfrującego hasła. Masz dostępna sól, i te wszystkie Twoje możliwości dla jednego hasła. Co byś zrobił z taką bazą ? bo ja bym skopiował adresy email i gdzieś sprzedał - jeśli byłoby co. Na pewno nie tworzyłbym bazy gdzie na jednego usera przypada niewiadomo ile kombinacji jednego hasła. Dopóki nie ma się dostępu do kodu(logiki), to każde zmielone przez coś hasło jest praktycznie nie do odgadnięcia. I analogicznie, jeśli znasz logikę to żadna kombinacja Ci nie pomoże
co do:
Cytat
Na standardowej klawiaturze możesz wprowadzić 98 znaków, więc na złamanie każdego hasha potrzeba max 98 prób. IMO średnia będzie oscylowała w okolicach 50.

no dobra masz bazę danych i kombinujesz czy złapiesz kolizje na pojedynczy znak.
no to ja teraz robie tak, że kazdą litere hasła powiele przez samą siebie np 10 razy i dodam jeszcze jakąś cyfre (np pozycja w ciągu)- i w ten sposób zapisze w bazie:
aaaaaaaaaa1
bbbbbbbbbb2
ccccccccccc3
dddddddddd4 (oczywiscie w przemielonej postaci)

i co teraz ? na stronie będzie działać bo będę mieć odpowiednio napisany skrypt, a ty jak na to wpadniesz ?

Cytat
a stawiam browara.

nie lubie jak ktoś mi obiecuje browar, którego i tak nie postawi ; )

wykradzioną bazę danych to Ty sobie dodałeś. Zazwyczaj pierwsza linią ataku jest sam formularz no ale co tam ;p widocznie łatwiej jest ukraść bazę ;p
sowiq
Cofnij się o jeden post i zerknij w linka, którego wkleił redeemer - security by obscurity
Cytat
Security through obscurity lub security by obscurity (z ang. bezpieczeństwo poprzez niezrozumiałość) to przykład złych praktyk stosowanych w bezpieczeństwie teleinformatycznym, którego istotą jest ukrywanie detali dotyczących implementacji, formatów i protokołów przed potencjalnymi adwersarzami. Osoby stosujące tę technikę wierzą, że nawet jeśli system posiada luki, nieznajomość błędów uniemożliwia przeprowadzenie ataku.


Druga sprawa - jeśli zagłębiłbyś się w treść wątku, zauważyłbyś, że od początku piszemy o stronie backendowej biorąc pod uwagę, że ktoś może wykraść bazę danych. W innym przypadku cała dyskusja nie miałaby sensu, bo hasło można by trzymać w bazie plaintextem.

Cytat
nadal nie wiem co jest w tym prostszego od jednego globalnego tokena ?

Proszę, oto kod dla znanej soli (zapisana w bazie):
  1. $hash = '$6$rounds=7000$bg#v{L]661?c2}1W$LfdyxcbiXpmNpyBt0oePFLnEXfvu5qbvN/916f60Mu/0CzoU2hh7G/LguOEMKD5a1uU39Xb3jSL/sORS2GiB/1';
  2. $salt = '$6$rounds=7000$bg#v{L]661?c2}1W';
  3.  
  4. $letters = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i');
  5. foreach($letters as $letter){
  6. if(crypt($letter, $salt) === $hash){
  7. echo $letter;
  8. }
  9. }


Cytat
no to ja teraz robie tak, że kazdą litere hasła powiele przez samą siebie np 10 razy

Nom, świetny pomysł smile.gif Zamieńmy wszystkie 'a' na 'aaaaaaaaaa'. Problem w tym, że tak samo jak hash(a) = hash(a), tak hash(aaaaaaaaaa) = hash(aaaaaaaaaa) wink.gif

Cytat
i dodam jeszcze jakąś cyfre (np pozycja w ciągu)

Tutaj racja, pozwoli to ograniczyć kolizje do takich samych znaków na tej samej pozycji. Ale też nie widzę problemu, żeby zamiast 'a' sprawdzić 'a1', 'a2', ... 'a20'.

Cytat
i co teraz ? na stronie będzie działać bo będę mieć odpowiednio napisany skrypt, a ty jak na to wpadniesz ?

Patrz wyżej - security by obscurity

Cytat
wykradzioną bazę danych to Ty sobie dodałeś. Zazwyczaj pierwsza linią ataku jest sam formularz no ale co tam ;p widocznie łatwiej jest ukraść bazę ;p

To po co przejmować się w ogóle jakimkolwiek hashowaniem? smile.gif Trzymaj hasła w plaintext i cześć wink.gif
Crozin
@NetBeans: Przede wszystkim nie powinieneś w ogóle takiego systemu wprowadzać. Nie mam pojęcia dlaczego niektóre banki coś takiego stosują. Na pierwszy rzut oka nie dostrzegam żadnych zalet takiego rozwiązania, a niemałych wad od razu rzuca się w oczy:
1. Jest to strasznie niewygodne dla użytkownika. Ciężko wpisuje się niekompletne hasło. Przed chwilą sprawdziłem sobie przy pomocy stopera: wpisanie kompletnego hasła zajmuje mi ok. 5 sekund (niemal 20 losowych znaków (w tym znaki specjalne)), zaś wpisanie zaledwie czterech losowych znaków hasła (korzystając z takiego samego formularza co na załączonym w pierwszym poście obrazku) ponad 10 sekund. Nie dość, że jest to niewygodne to jeszcze obniża poziom bezpieczeństwa - zawsze im krótszy ciąg tym łatwiej go złamać, chociażby brute-forcem.
2. Implementacja takiego mechanizmu ułatwia życie osobie łamiącej hasło. Załóżmy, że posiadam 10 znakowe hasło (1234567890), które zostało zapisane jako jeden kompletny hash oraz 5 wariantów do wpisania 4 znaków (0389; 1086; 4390; 6320; 7368 - cyfra w tym przypadku od razu odpowiada pozycji znaku). Jeżeli udałoby mi się złamać tych 5 niekompletnych haseł bez problemu powinienem móc utworzyć z nich kompletne hasło główne. A złamanie tych 5 niekompletnych haseł jest dziecinnie proste w porównaniu do złamania hasła głównego. Zakładając, że dostępna pula znaków składa się z 70 elementów (a-zA-Z0-9 + znaki specjalne) złożoność obu operacji różni się o 10 rzędów wielkości!

PS. SHA-x nie nadają się do hashowania haseł, od tego są funkcje typu blowfish.
PS2. Powinieneś od razu założyć, że atakujący ma dostęp do absolutnie wszystkiego poza oryginalnym hasłem użytkownika.
phpion
Cytat(Crozin @ 18.07.2013, 13:23:31 ) *
Nie mam pojęcia dlaczego niektóre banki coś takiego stosują.

W przypadku zainstalowania jakiegoś keyloggera złośliwa istota będzie miała tylko wybrane pojedyncze znaki z hasła, a nie całe hasło.
Crozin
Cytat
W przypadku zainstalowania jakiegoś keyloggera złośliwa istota będzie miała tylko wybrane pojedyncze znaki z hasła, a nie całe hasło.
To już jest jakiś argument, jednak żeby w ogóle zalogować się do banku/konta i tak trzeba najpierw podać pełne hasło. Przed keyloggerami zdecydowanie lepiej broni wirtualna klawiatura, ale wymuszenie jej użycia to czysty sadyzm. wink.gif
Damonsson
A co z czymś takim:

Hasło: alamakota

Hash hasła w bazie: ewhf9rh329fheufbssdfunsdifus (byle jaki, byle jakiś ciężki do dopasowania)

Formularz do wpisania: []x[][]xxxx[]

Skrypt PHP, przekazujący litery z pozycjami, porównujący: axamxxxxa do alamakota ; w pętli, podstawia za X wszystkie możliwe znaki, hashuje i porównuje z hasłem w bazie.

Nie trzeba nic rozbijać, dzielić itp.

Tylko problemem może być czas dopasowania do prawdziwego hasła, ale na dobrym sprzęcie optymalnie napisany skrypt, chybaby podołał tematowi?

edit: @up: Nie trzeba podawać całego hasła przy logowaniu do banku, tylko właśnie te wybrane litery.
nospor
Cytat
Skrypt PHP, przekazujący litery z pozycjami, porównujący: axamxxxxa do alamakota ; w pętli, podstawia za X wszystkie możliwe znaki, hashuje i porównuje z hasłem w bazie.
No to w tym momencie tylko ulatwiasz hakerowi atak i odwalasz za niego brute force (a przynajmniej dużą cześc) smile.gif
redeemer
Cytat(Damonsson @ 18.07.2013, 13:48:35 ) *
Tylko problemem może być czas dopasowania do prawdziwego hasła, ale na dobrym sprzęcie optymalnie napisany skrypt, chybaby podołał tematowi?
Nie.
freemp3
Cytat(Crozin @ 18.07.2013, 13:42:56 ) *
jednak żeby w ogóle zalogować się do banku/konta i tak trzeba najpierw podać pełne hasło

No właśnie o to chodzi, że nie trzeba smile.gif Przykładowo w BZ WBK czy ING należy podać tylko literki, o które poprosi system. W mBanku w starym systemie do logowania jest konieczność podawania całego hasła.
Co do keyloggera to na upartego uda się zdobyć hasło, ale trzeba zebrać trochę danych i je przeanalizować, ale wątpie, żeby komuś się chciało to robić, żeby się dostać na konto szarego Kowalskiego smile.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.