Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Bezpieczeństwo haseł przy użyciu soli
Forum PHP.pl > Inne > Hydepark
nexis
Zwykle, dla bezpieczeństwa, trzymamy w bazie danych skrót hasła, utworzony za pomocą md5() bądź sha1(). Z myślą o tęczowych tablicach dopisujemy zwykle dodatkowo tzw. sól, która jest trzymana poza bazą danych, zwykle na serwerze.

Chciałbym jednak zwiększyć bezpieczeństwo również po stronie użytkownika i zastosować mechanizm znany z banków internetowych, czyli odpytywanie użytkownika o wybrane znaki hasła. Aby zastosować taki mechanizm jestem jednak zmuszony zapamiętać każdy znak hasła osobno. Powiedzmy, że w tym celu narzucę maksymalną długość hasła na 16 znaków i stworzę w tabeli bazy danych 16 dodatkowych pól (po 1 dla każdego znaku). Jak ma się jednak w/w sposób do tej sytuacji? Sam skrót to praktycznie żadne zabezpieczenie. Zastosowanie soli już bardziej, ale jest to wciąż bardzo słaby mechanizm. Co zrobić?
thek
Osobiście nigdy tak nie podchodziłem do sprawy bezpieczeństwa, ale myślę, że pewnymrozwiązanem byłoby tualbo napisanie własnego szyfru albo użycie już istniejącego. Ważne by był dwukierunkowy. Można do niego także dodawać sól czy co tam chcesz. Ważne tylko tyle, by zastosować przy tym jakiś algorytm odwracalny, by móc hasło uzyskać z ciągu. Możnanawet potem jeszcze nakilka pól w bazie rozbić i zamieniać kolejność elementów by utrudnić,ale czy jest większy sens aż takiego kombinowania to nie wiem. Myślę, że Najlepiej by sę tu sprawdził jakiś własny algorytm mieszająco-szyfrujący. Bo też większość łamaczy polega na kilku znanych algorytmach.
sztosz
Akurat dwukierunkowość szyfrowania to nie jest dobry pomysł. Po to są algorytmy jedno kierunkowe żeby na podstawie zaszyfrowanego hasła nie można było odzyskać wersji nie zaszyfrowanej.
blooregard
Cytat
Akurat dwukierunkowość szyfrowania to nie jest dobry pomysł.

Akurat zgodzę się z @thekiem. Masz rację @sztos, co do funkcji haszujących, jednak zauważ, jaki problem ma @nexis: chodzi mu o podawanie wybranych znaków z hasła (o długości 16 znaków). Powiedz mi, jak chcesz to rozwiązać stosując haszowanie? Tu nie ma wyjścia - gdzieś musi być zapisane hasło w takiej postaci, by dało się z niego "wyciągnąć" te 5 znaków oraz ich pozycje w całym haśle do porównania.

I tu może tkwi problem: nie w sposobie zabezpieczenia samego hasła (bo do tego mozna użyć, tak jak wskazał @thek, autorskiego algorytmu, który niczym nie przypominałby tych najpopularnieszych, ale byłby odwracalny), ale właśnie w sposobie jego przechowywania. Np. hasło podzielone na fragmenty i każdy fragment przechowywany w osobnej bazie danych, na fizycznie innej maszynie?

Swoją drogą, ciekaw jestem bardzo, jak te kwestie mają rozwiązane od strony programistycznej wspomniane banki. Bo mój też stosuje takie zabezpieczenie.
phpion
Cytat(blooregard @ 3.09.2009, 20:41:13 ) *
Tu nie ma wyjścia - gdzieś musi być zapisane hasło w takiej postaci, by dało się z niego "wyciągnąć" te 5 znaków oraz ich pozycje w całym haśle do porównania.

Niekoniecznie. Równie dobrze można trzymać hashe poszczególnych liter hasła w osobnych rekordach i wówczas odpada nam problem jawnego przetrzymywania haseł w bazie.
sztosz
Masz hasło x znaków, haszujesz każdy znak, hasz ma długość n znaków, czyli całe hasło będzie w bazie zapisane w ciągu o długości x*n znaków. Znak trzeci hasła ma hasz y, hasz y zaczyna się dokładnie po n*2 znaków a kończy dokładnie w miejscu n*4 znaków zahaszowanego hasła w bazie danych. Nie ma problemu. Jedyny ew, problem to to że najpierw użytkownik wysyła login, a dopiero po przeładowaniu strony, czy normalnie, czy ramki ajaxem, poszczególne litery hasła losowo wybrane z tego które jest w bazie. Tak więc jest wyjście.
nexis
Póki co przyszło mi na myśl stosowanie bardzo złożonej soli, np. 32 znakowej lub wyższej, indywidualnie dla każdego użytkownika. Sól musiałaby być trzymana oczywiście poza bazą danych, np. na serwerze w pliku tekstowym lub w niezależnej bazie danych.

Wtedy mając hasło typu abcd1234 i sól dRazeV!SAkEpe5UquP7udrap6*re3HuG pamiętamy, tak jak poprzednio proponowałem, skrótu dla każdego znaku oddzielnie:

adRazeV!SAkEpe5UquP7udrap6*re3HuG
bdRazeV!SAkEpe5UquP7udrap6*re3HuG
cdRazeV!SAkEpe5UquP7udrap6*re3HuG
ddRazeV!SAkEpe5UquP7udrap6*re3HuG
1dRazeV!SAkEpe5UquP7udrap6*re3HuG
2dRazeV!SAkEpe5UquP7udrap6*re3HuG
3dRazeV!SAkEpe5UquP7udrap6*re3HuG
4dRazeV!SAkEpe5UquP7udrap6*re3HuG

Można nawet pójść dalej i stosować różną sól dla każdego znaku i użytkownika (n x n). Wtedy mielibyśmy pewność, że ciąg pusty (np. dla hasła 8 znakowego, pozostałe 8 z 16 znaków) miałby różny skrót dla każdego znaku.

Cytat(sztosz @ 3.09.2009, 21:48:40 ) *
Masz hasło x znaków, haszujesz każdy znak, hasz ma długość n znaków, czyli całe hasło będzie w bazie zapisane w ciągu o długości x*n znaków. Znak trzeci hasła ma hasz y, hasz y zaczyna się dokładnie po n*2 znaków a kończy dokładnie w miejscu n*4 znaków zahaszowanego hasła w bazie danych. Nie ma problemu. Jedyny ew, problem to to że najpierw użytkownik wysyła login, a dopiero po przeładowaniu strony, czy normalnie, czy ramki ajaxem, poszczególne litery hasła losowo wybrane z tego które jest w bazie. Tak więc jest wyjście.

Tylko jeśli ktoś zna budowę tego ciągu, to podzieli sobie ten ciąg na poszczególne znaki, a odczytanie skrótu md5() czy też sha1() z jednoznakowego wyrazu to małe piwo.
blooregard
Cytat
Równie dobrze można trzymać hashe poszczególnych liter hasła w osobnych rekordach i wówczas odpada nam problem jawnego przetrzymywania haseł w bazie.


A ile takich haszy uzyskasz z 26 liter alfabetu? 26. A jaki szyfr jest najprostszy do złamania? Podstawieniowy (każdej literze alfabetu odpowiada inny znak, w tym przypadku byłby to hasz, a nie pojedyńczy znak, czyli w sumie jedynie 26 RÓŻNYCH haszy).A sposobów na złamanie takich szyfrów są dziesiątki (analiza częstotliwościowa na przykład).

Ale można byłoby tworzyć hasz np. z litery i cyfry określającej jej pozycję w haśle. Wtedy dla jednego 16-znakowego hasła mamy już 26 liter * 16 możliwych pozycji jej występowania w haśle (czyli 416 haszy). Przy podawaniu hasła trzeba byłoby sprawdzać np, dla literki a na 6-tej pozycji hasz dla ciągu 'a6', w szóstym rekordzie tabeli zawierającej hasła. Ale to niewiele wzmocniłoby ten algorytm.

Albo dla litery i dwóch cyfr, określających jej pozycję od początku i końca hasła (czyli np. 6a10 - litra 'a' na 6 pozycji, czyli 10-ta od końca). No to już nam daje 26*16*16 = 6656 róznych haszy w bazie, co już raczej utworzyłoby w niej artystyczny bałagan. Do tego jeszcze np. mozna dodac część całkowitą powstałą z dzielenia tych pozycji ('6a100' - litera 'a' na 6 pozycji, 10 od końca, oraz 0 jako część całkowita z dzielenia 6/10), co daje nam już 6-znakowy ciąg. To czyni zabezpieczenie jeszcze silniejszym.

Oczywiście siłę całego zabezpieczenia zwiększą użycie dużych/małych liter oraz cyfr. Wtedy takie rozwiązanie zaczyna mieć sens. Albo tak mi się tylko wydaje. smile.gif

nexis
Cytat(blooregard @ 3.09.2009, 22:04:11 ) *
Albo tak mi się tylko wydaje. smile.gif

Stworzenie bazy zawierającej nawet milion hashy to kwestia kilku minut. Nie sposób posłużyć się Security through obscurity, czyli ukrywaniem sposobu powstania hasha. Chodzi o to, żeby sposób był bezpieczny nawet ujawniając kod źródłowy aplikacji!
blooregard
Cytat
Chodzi o to, żeby sposób był bezpieczny nawet ujawniając kod źródłowy aplikacji!

A czy to w ogóle jest możliwe?

Logicznie rzecz biorąc, aplikacja jakoś MUSI porównać podane hasło z tym zapisanym w bazie. A skoro musi, to jest to jednoznaczne z tym, że sposób tego porównania musi być w niej zapisany.
nexis
Cytat(blooregard @ 3.09.2009, 22:22:00 ) *
A czy to w ogóle jest możliwe?

Tak, ponieważ chodzi o kod źródłowy samej aplikacji, czyli m.in. sposobu powstania skrótów dla haseł użytkowników. Ale warto pamiętać, że nie chodzi tutaj o wgląd w wygenerowane później przez system sole itd., bo to oczywiście mijałoby się z celem. Efekt ma być taki, że po przejęciu kontroli nad serwerem ze skryptami, atakujący nie jest w stanie odczytać haseł i tak samo nie będzie w stanie ich odczytać po przejęciu kontroli nad bazą danych.
blooregard
Cytat
Efekt ma być taki, że po przejęciu kontroli nad serwerem ze skryptami, atakujący nie jest w stanie odczytać haseł i tak samo nie będzie w stanie ich odczytać po przejęciu kontroli nad bazą danych.

Chyba, że przejmie kontrolę nad oboma serwerami. Wtedy pozamiatane.
nexis
Cytat(blooregard @ 3.09.2009, 22:32:38 ) *
Chyba, że przejmie kontrolę nad oboma serwerami. Wtedy pozamiatane.

Zdaje się, że jest i na to sposób. Skrót powinien być generowany na podstawie:
  1. pojedynczego znaku hasła
  2. indywidualnej soli dla każdego znaku i każdego użytkownika (n x n)
  3. stałej soli zapisanej na serwerze i skompilowanej do kodu pośredniego (mam tutaj na myśli np. ionCube)


Cały kod aplikacji (stały) powinien być więc skompilowany do kodu pośredniego, przez co jego odczytanie staje się niemożliwe przez człowieka. Chronimy tym samym dostęp do bazy danych po przejęciu ew. kontroli nad serwerem, ponieważ dane dostępowe do bazy danych również nie były możliwe do odczytania.

Widzi ktoś wady takiego rozwiązania?
blooregard
Cytat
Widzi ktoś wady takiego rozwiązania?

No nie, w tym momencie to już raczej potencjalne włamanie nawet na oba serwery nic nie da, bo nie ma dostępu do algorytmu porównywania hasła. A z samych haszy, których przy uzyciu jakiegoś skomplikowanego algorytmu może być tyle, że skutecznie uniemozliwi to atak np. brute force czy inne metody. Tym bardziej, że rozdzieliliśmy znaki hasła na osobne rekordy.
Zakładając, że kodu PHP skompilowanego dokodu pośredniego nie da się dekompilować smile.gif

Swoją drogą nadal jestem ciekaw, jak to wygląda "w realu".

thek
Zastanawiałem się Nexis nad algorytmem, który dawałby odpowiedź na punkt 2 i myślę, że da się zrobić jeszcze większą zamotę z solą indywidualną. Na dodatek byłoby to jeszcze o kolejny "mnożnik" powiększone. Mianowicie pozycja litery do odczytu z hasła wskazywałaby na jakąś inną w odczytywalnym ciągu znaków i jej hash dodawany byłby do ciągu jeszcze przed hashowaniem jako kolejna sól. W ten sposób dochodziłaby sól zmienna. O co mi chodzi? Przykład
Mamy ciąg odczytywalny loginu (ale może to być dowolny inny ciąg znakowy, najlepiej taki, którego nie przechowujemy nigdzie w sesjach):
jakiś_tam_user
Mamy też hasło
haslo_usera
I chcemy poznać 8 literę hasła, czyli 's', więc pobieramy też 8 (możemy ustalić tutaj inną niż 8, na przykład (kolejność_litery + 5)%jakas_z_zakresu_[2,długość_loginu] ) literę loginu 'a'
teraz robimy hash('a').'s'.salt_jeszcze_jakiś
Co zyskujemy?
1. Dla dwóch userów z tym samym hasłem prawdopodobieństwo wystąpienia tej samej litery w określonym miejscu jest niższe co sprawia, że hashe będą różne, gdyż hasło 'kjlvkdfj' wygeneruje dla userów "mastah" i "gostek" częściowo inne hashe znaków.
2. Dla tej samej litery na różnych pozycjach prawdopodobieństwo wygenerowania hasha identycznego także znacznie spada, dzięki czemu ta sama litera u tego samego usera ale w różnych miejscach najprawdopodobniej wygeneruje inny hash, przez co zwykłe podstawianie zapewne szlag trafi winksmiley.jpg Wystarczy spojrzeć na litery 's' i 'a' w haśle. 's' będzie miał hashe liczone od 'k' i 't'. Zaś 'a' hashe od 'a' i '_'. To daje o wiele więcej kombinacji niż n*n*n, bo też do jednego znaku może być przypisane kilka kodów nawet hasło "aaaaaa" wygeneruje inne hashe dla poszczególnych liter 'a' przy loginie typu "konwersja".

EDIT: Podoba mi się ten temat, bo lubię zajmować się ciekawymi zagadnieniami teoretycznymi. A pomysły tutaj rzucane myślę, że są ciekawym uzupełnieniem tematu o bezpieczeństwie smile.gif W końcu ludzie zdają się zazwyczaj na domyślne algorytmy bezpieczeństwa, a my teraz zajmujemy się w sumie autorskimi metodami autoryzacji użytkownika.
nexis
Cytat(thek @ 4.09.2009, 10:34:43 ) *
Dla dwóch userów z tym samym hasłem prawdopodobieństwo wystąpienia tej samej litery w określonym miejscu jest niższe co sprawia, że hashe będą różne

Sprawa indywidualnych soli załatwia już tą sprawę, więc mam wrażenie, że niepotrzebnie komplikujesz.
thek
Może i tak, ale indywidualna sól dla każdego użytkownika rozwiązuje sprawę tylko na poziomie grupy użytkowników. Jeśli ktoś chciałby jednak poznać hashe konkretnych znaków dla konkretnego usera, wystarczy że będzie je podstawiał i może próbować z częstotliwości wnioskować. Zwłaszcza przy dłuższych hasłach. Tutaj właśnie pojawia się problem "odwrotnej skuteczności zabezpieczania" czy "paradoks paranoidalności" jak ja je nazywam. Im dłuższe hasło tym prościej je złamać algorytmami bazującymi na częstotliwości występowania znaku dla danego użytkownika. Wystarczy, że user kilkukrotnie zmieni hasło na inne i będzie można porównać częstotliwość występowania danego skrótu. Tak więc najbardziej dbający o bezpieczeństwo użytkownicy, zmieniający hasła często, są najbardziej narażeni na jego złamanie. Dlatego też proponowałem wprowadzenie elementu "pseudolosowego" dla każdej litery. Tak, by nie zwracała ona za każdym razem tego samego po zastosowaniu algorytmu smile.gif
nexis
Wciąż nie widzę w czym zaprezentowana przez ciebie metoda przewyższa bezpieczeństwo przy użyciu indywidualnych soli dla każdego użytkownika i każdego znaku hasła, czyli np. dla hasła abcd1234 pamiętamy:

sha1(sól_główna + sól1 + a)
sha1(sól_główna + sól2 + b)
sha1(sól_główna + sól3 + c)
sha1(sól_główna + sól4 + d)
sha1(sól_główna + sól5 + 1)
sha1(sól_główna + sól6 + 2)
sha1(sól_główna + sól7 + 3)
sha1(sól_główna + sól8 + 4)
thek
To przemyśl co da hasło abababab skoro dla każdej litery jest ta sama sól zawsze. Bo jeśli dobrze zrozumiałem Twoje rozumowanie, to "każdy user ma swój hash i każda litera ma swój hash". W wyniku dostaniemy:
sha1(sól_główna + sól1 + a)
sha1(sól_główna + sól2 + b)
sha1(sól_główna + sól1 + a)
sha1(sól_główna + sól2 + b)
sha1(sól_główna + sól1 + a)
sha1(sól_główna + sól2 + b)
sha1(sól_główna + sól1 + a)
sha1(sól_główna + sól2 + b)
Sól główna jest stała, a każda litera ma swoją własną sól. Przy czym można wnioskować, że sole dla całego zakresu znaków są stałe, niezależnie od tego u jakiego usera. W moim pomyśle nawet wystąpienie kilkukrotne tej samej litery wprowadziło by różne skróty dla nich w wyniku. Poza tym w takim wypadku jak ja Cię zrozumiałem niepotrzebne jest używanie znaku na końcu, gdyż i tak jego hash jest identyczny. Nie robi więc różnicy czy użyję "sól+jego_znak" czy samo "sól" w funkcji skrótu, gdyż i tak w wyniku dostanę tak czy inaczej przy każdym powtórzeniu ten sam hash. Czy więc użycie 'mambaA' i 'mamba' da coś więcej poza innym nieco hashem. To i tak nieistotne dopóki będzie się za każdym razem dostawać ten sam. Mi bardziej zależy na tym, by algorytm generował inny hash dla 'mamba' w zależności od tego na jakiej pozycji jest litera do weryfikacji, bo może się okazać, że wtedy do funkcji skrótu nie trafi mamba ale 'mbaca' co zmieni już wynik hashowania, mimo że zostały wywołane dla tej samej litery. Zresztą czy zastanawiałeś się nad tym, gdzie przechowywać sole dla zakresu (odpada jeśli sa generowane w locie).
Jeśli jednak planowałeś generować dla każdego usera jego własne sole dla całego zakresu to gdzieś też musiałbyś je przechowywać do porównania.

EDIT: Pozwól że rozpiszę przykład aaaaaaaa

Twój kod:
sha1(sól_główna + sól1 + a)
sha1(sól_główna + sól1 + a)
sha1(sól_główna + sól1 + a)
sha1(sól_główna + sól1 + a)
sha1(sól_główna + sól1 + a)
sha1(sól_główna + sól1 + a)
sha1(sól_główna + sól1 + a)
sha1(sól_główna + sól1 + a)

Mój kod:
sha1(sól_główna + sól_generowana_dla_znaku_na_pozycji_1_modulo_długość_ciągu_w_jakiejś_danej_tekst
owej)
sha1(sól_główna + sól_generowana_dla_znaku_na_pozycji_2_modulo_długość_ciągu_w_jakiejś_danej_tekst
owej)
sha1(sól_główna + sól_generowana_dla_znaku_na_pozycji_3_modulo_długość_ciągu_w_jakiejś_danej_tekst
owej)
sha1(sól_główna + sól_generowana_dla_znaku_na_pozycji_4_modulo_długość_ciągu_w_jakiejś_danej_tekst
owej)
sha1(sól_główna + sól_generowana_dla_znaku_na_pozycji_5_modulo_długość_ciągu_w_jakiejś_danej_tekst
owej)
sha1(sól_główna + sól_generowana_dla_znaku_na_pozycji_6_modulo_długość_ciągu_w_jakiejś_danej_tekst
owej)
sha1(sól_główna + sól_generowana_dla_znaku_na_pozycji_7_modulo_długość_ciągu_w_jakiejś_danej_tekst
owej)
sha1(sól_główna + sól_generowana_dla_znaku_na_pozycji_8_modulo_długość_ciągu_w_jakiejś_danej_tekst
owej)

Problemem jest teraz u Ciebie powtarzanie się hashy. U mnie pewne mogą się powtórzyć, ale jest to o wiele mniej prawdopodobne, gdyż musiałoby dojść do sytuacji, że ciąg musiałby mieć na tych samych pozycjach te same znaki. i byłoby to jednoznaczne choćby z ciągiem 'cccccccccccccc'.
Ale użycie dowolnego innego jak 'dowolny_ciąg' dałoby te same znaki tylko dla litery 'o'. Choć więc hasło jest z samych literek 'a' to każda z nich niemal ma inny hash po przejściu funkcji ;)
blooregard
Cytat
Bo jeśli dobrze zrozumiałem Twoje rozumowanie, to "każdy user ma swój hash i każda litera ma swój hash".

Chyba chodziło o to, że każda pozycja w haśle ma własną sól, więc abababab dałoby cos takiego:
sha1(sól_główna + sól1 + a )
sha1(sól_główna + sól2 + b )
sha1(sól_główna + sól3 + a )
sha1(sól_główna + sól4 + b )
sha1(sól_główna + sól5 + a )
sha1(sól_główna + sól6 + b )
sha1(sól_główna + sól7 + a )
sha1(sól_główna + sól8 + b )

i wtedy dla liter a na pozycjach 1,3,5 i 7 hasze będą inne, analogicznie dla liter b.
thek
Po przeczytaniu posta odnosi się wrażenie, że nie chodzi o to by pozycja miała jakiś hash, tylko że konkretna litera ma jakiś przypisany jej skrót. Dla mnie zrozumiałe jest, że powinno być coś w stylu o jakim piszesz blooregard, czyli niezależność znaków w haśle od ich hashy. Stąd właśnie ja zrobiłem zależność skrótu od zupełnie innego pola, bo to w tym momencie daje pole do popisu. Musiałbyś mieć dokładny kod aplikacji i dokładną kopię bazy. Jako admin wystarczy tylko pilnować aktualizacji tabeli gdy user zmieniałby pole na podstawie którego generujesz hashe. Ale to jest w tym właśnie najfajniejsze... Każda zmiana w "profilu" pociągałaby za sobą zmianę wyniku pól porównywanych. Jeśli więc ma hacker zrzut bazy choćby na 5 minut przed tym gdy użytkownik zmienił zawartość pola "newralgicznego" to włamywacz ma stare hashe, które są już nieaktualne mimo faktu nie zmienionego hasła smile.gif Można też, by było zabawniej, generować takie pole co jakiś czas i zapisywać do bazy jako niewidoczne dla usera. Coś w stylu tokena winksmiley.jpg To dawałoby nam niemal nieograniczoną liczbę kombinacji.
nexis
Cytat(thek @ 4.09.2009, 14:21:41 ) *
Twój kod:
sha1(sól_główna + sól1 + a)
sha1(sól_główna + sól1 + a)
sha1(sól_główna + sól1 + a)
sha1(sól_główna + sól1 + a)
sha1(sól_główna + sól1 + a)
sha1(sól_główna + sól1 + a)
sha1(sól_główna + sól1 + a)
sha1(sól_główna + sól1 + a)

Niestety źle mnie zrozumiałeś. Mam na myśli coś tego typu:

Sól systemowa: 6R$fr2Ga

Nazwa użytkownika: adam
Hasło: abcd1234
Skróty w bazie danych:
sha1(6R$fr2Ga + CRu6$wRu + a)
sha1(6R$fr2Ga + cuthA3=R + b)
sha1(6R$fr2Ga + th$PhE3u + c)
sha1(6R$fr2Ga + +RUt*uF2 + d)
sha1(6R$fr2Ga + =r9cH6!u + 1)
sha1(6R$fr2Ga + F7ecR-ph + 2)
sha1(6R$fr2Ga + _EKa73@w + 3)
sha1(6R$fr2Ga + p@$VE96u + 4)

Nazwa użytkownika: ewa
Hasło: abcd1234 (takie samo jak użytkownika "adam")
Skróty w bazie danych:
sha1(6R$fr2Ga + R$ga@AdU + a)
sha1(6R$fr2Ga + 9e-r*sAs + b)
sha1(6R$fr2Ga + gE*ekUp7 + c)
sha1(6R$fr2Ga + H#wru3at + d)
sha1(6R$fr2Ga + z2=U7Huf + 1)
sha1(6R$fr2Ga + jeD+ut4C + 2)
sha1(6R$fr2Ga + du6*aPag + 3)
sha1(6R$fr2Ga + 2?_tE3Ra + 4)

Sól systemowa i poszczególne sole będą trzymane po stronie serwera ze skryptami (poza bazą danych). Czy jest możliwość złamania tego? Bo tylko wtedy widzę potrzebę jakichkolwiek dodatkowych kombinacji.

Sole mogą, a nawet powinny, być bardziej złożone (> 32 znaków), ale podałem krótsze dla zwiększenia czytelności.
thek
Ok... Pomińmy więc w dalszych rozważaniach sól systemową i skupmy na owej drugiej. W tym momencie powiedz mi jak wygląda sprawa soli w przypadku gdy hasło użytkownika zawiera te same znaki. Jak na razie bowiem przerabiamy temat gdy znaki w haśle są unikatowe (abcd1234), a ja staram dowiedzieć jak w zamyśle Twój algorytm działa w przypadku haseł w stylu (aaaaaaaa). Zauważ, że fragment jaki zresztą zacytowałeś taki wątek porusza. Na razie rozważasz bowiem w przykładach sytuację, gdy żaden ze znaków się nie powtarza. Z postów zaś wynika, iż każdy znak ma swój hash. Dlatego też napisałem w 8 przypadkach 'sól1 + a', bo tak można wnioskować że algorytm działa, z tego co do tej pory napisałeś. A to jest niebezpieczne bo dla tego samego znaku, hash każdego takiego samego będzie identyczny, niezależnie ile soli do niego władujesz. No chyba, że po prostu każdy użytkownik ma swój własny zestaw hashy dla określonych pozycji. Tylko jak zamierzasz to na serwerze zorganizować? Załóżmy 1000 userów, z których każdy ma hasło około 10-15 znakowe. To daje nam całkiem pokaźną ilość hashy do przechowywania gdzieś na serwerze oraz, co istotniejsze systemu zapisu/odczytu tego pakietu, który mocno wpłynie na wydajność zapewne. Zresztą przy zmianie hasła na dłuższe też musiałbyś jakoś rozwiązać problem dopisania nowych hashy do tej "bazy". Problem bezpieczeństwa staje się więc jednocześnie wąskim gardłem w wydajności :/ Algorytm powinien więc być na tyle bezpieczny by dane na których operuje mogły być przechowywane w bazie i/lub mogły być generowane w locie. Stąd zaproponowałem funkcję losowego tokena zmienianego co jakiś określony czas i który byłby składową przy generowaniu zestawu hashy porównawczych dla danego usera. Każda zmienna bowiem to plus dla bezpieczeństwa, gdyż niweluje nam niezmienność takich danych jak hasło lub pewne ciągi wejściowe użyte podczas procesu generowania ciągów hashy porównawczych.
nexis
Cytat(thek @ 4.09.2009, 23:07:25 ) *
staram dowiedzieć jak w zamyśle Twój algorytm działa w przypadku haseł w stylu (aaaaaaaa)

Podstaw sobie dowolne hasło pod podany przeze mnie, w poprzednim poście, wzór i znałbyś odpowiedź na swoje pytanie. Zakładam, że każdy użytkownik ma unikalną sól dla każdego pojedynczego znaku hasła.

Cytat(thek @ 4.09.2009, 23:07:25 ) *
Załóżmy 1000 userów, z których każdy ma hasło około 10-15 znakowe. To daje nam całkiem pokaźną ilość hashy do przechowywania gdzieś na serwerze oraz, co istotniejsze systemu zapisu/odczytu tego pakietu, który mocno wpłynie na wydajność zapewne.

Założyłem, że maksymalna długość hasła będzie wynosiła 16 znaków, więc pełny zestaw soli zostaje generowany już przy rejestracji nowego użytkownika. Jako metodę przechowania soli proponowałem system plików, ale można równie dobrze wykorzystać niezależną bazę danych i przechowanie nawet 16 soli dla każdego użytkownika nie wpłynie praktycznie w żaden sposób na wydajność. Szczególnie, że dane są pobierane jedynie w takich przypadkach jak: rejestracja, logowanie czy zmiana hasła.
thek
Cytat
Podstaw sobie dowolne hasło pod podany przeze mnie, w poprzednim poście, wzór i znałbyś odpowiedź na swoje pytanie. Zakładam, że każdy użytkownik ma unikalną sól dla każdego pojedynczego znaku hasła.
No właśnie problem w tym, że tego się nie da z Twoich wzorów określić jednoznacznie bo nie określasz nigdzie czy owa dodatkowa sól jest uzależniona od pozycji:

sha1(6R$fr2Ga + CRu6$wRu + a)
sha1(6R$fr2Ga + cuthA3=R + a)
sha1(6R$fr2Ga + th$PhE3u + a)
sha1(6R$fr2Ga + +RUt*uF2 + a)
sha1(6R$fr2Ga + =r9cH6!u + a)
sha1(6R$fr2Ga + F7ecR-ph + a)
sha1(6R$fr2Ga + _EKa73@w + a)
sha1(6R$fr2Ga + p@$VE96u + a)

czy od znaku:
sha1(6R$fr2Ga + CRu6$wRu + a)
sha1(6R$fr2Ga + CRu6$wRu + a)
sha1(6R$fr2Ga + CRu6$wRu + a)
sha1(6R$fr2Ga + CRu6$wRu + a)
sha1(6R$fr2Ga + CRu6$wRu + a)
sha1(6R$fr2Ga + CRu6$wRu + a)
sha1(6R$fr2Ga + CRu6$wRu + a)
sha1(6R$fr2Ga + CRu6$wRu + a)

Teraz przeczytaj jeszcze raz zdanie swoje jakie zacytowałem powyżej i powiedz czy osoba logicznie myśląca uzna wariant 1 czy 2 za prawidłowy. Bo myślę, że oprócz mnie wiele osób pomyśli, iż jednak piszesz cały czas o wariancie 2. Ciągle bowiem przewija się fragment o unikalności dla każdego pojedynczego znaku hasła, a dla wielu może to oznaczać równoważność między dowolnym znakiem a odpowiadającym mu skrótem (tak jak to widać w wariancie 2 powyżej). Może po prostu źle to odbieram i nie myślę już przy weekendzie. Myślę, że powinniśmy się przespać chyba już dziś bo pewnie nie kontaktujemy oboje :D Ale myślę, że rozumiesz teraz na przykladzie o co mi chodzi i od następnego posta będziemy bardziej precyzyjni w doborze słów. Myślę, że zwrot: "każdy użytkownik ma unikalną sól dla każdej pozycji w swoim haśle jest łatwiejsze w odbiorze.
A jeśli już przy tym jesteśmy to może powinniśmy się zastanowić, czy te sole miały by być generowane losowo co jakiś czas na podstawie innego pola bazy, czy może generowane co jakiś czas i na sztywno wrzucane do bazy, czy może wyrzucić je poza katalog główny serwera (imho chyba najbezpieczniejsza metoda), czy też może jakiś plik na serwerze, którego nie można by było podejrzeć z poziomu przeglądarki ( na przykład próba wejścia wywoływała by jego interpretację).
nexis
Cytat(thek @ 5.09.2009, 01:05:41 ) *
Teraz przeczytaj jeszcze raz zdanie swoje jakie zacytowałem powyżej i powiedz czy osoba logicznie myśląca uzna wariant 1 czy 2 za prawidłowy.

Chodzi oczywiście cały czas o wariant 1.

Cytat(thek @ 5.09.2009, 01:05:41 ) *
czy te sole miały by być generowane losowo co jakiś czas na podstawie innego pola bazy, czy może generowane co jakiś czas i na sztywno wrzucane do bazy

Pamiętaj, że hasło znasz tylko w momencie, kiedy użytkownik je poda i porównasz jego prawidłowość ze skrótami. Wtedy ewentualnie masz możliwość zmiany soli i wpisanie nowego skrótu. Być może jest to słuszna uwaga odnośnie podwyższenia bezpieczeństwa. Proponuję zatem, żeby ktoś to potwierdził i wspólnie zaakceptowane rozwiązania wrzucę do pierwszego postu dla przyszłych czytelników, którym prawdopodobnie nie będzie się chciało czytać całych naszych dialogów.

Cytat(thek @ 5.09.2009, 01:05:41 ) *
wrzucane do bazy, czy może wyrzucić je poza katalog główny serwera (imho chyba najbezpieczniejsza metoda), czy też może jakiś plik na serwerze, którego nie można by było podejrzeć z poziomu przeglądarki ( na przykład próba wejścia wywoływała by jego interpretację).

Plik oczywiście musi leżeć poza strukturą dostępną z poziomu przeglądarki, ale to chyba kwestia oczywista. Podobne założenie trzeba oczywiście też przyjąć dla soli głównej i całego pliku konfiguracyjnego. Zdaje się, że niezależna baza danych jest w tym przypadku lepszym rozwiązaniem.
thek
Wczoraj w chwili przerwy przejrzałem nasze wypowiedzi i zauważyłem jedną rzecz. Algorytm nad jakimi dumamy ma jedną, poważną (moim zdaniem) wadę. Działa jak należy gdy wywołamy procedurę zmiany hasła jawnie (tworzenie nowego przez usera czy "zapomniane hasło"). Jednak przy zmianie czegoś w algorytmie (tokeny czasowe, zmiana soli itp. ) będziemy leżeli i kwiczeli. Przy zmianie nikt nic nie będzie mógł autoryzować lub w skrajnym przypadku (jeśli prośba o podanie znaku z pozycji określonej wyskoczy przy logowaniu) nie zaloguje się. Błąd wynika z tego, że hashe porównawcze są generowane na podstawie istniejącego hasła. Każda więc zmiana pociąga za sobą konieczność generowania nowych hashy a więc i wymusza znajomość jawnej postaci hasła. Stąd też myślę, że konieczne byłoby uniezależnienie się algorytmu od tego typu luki. Moim zdaniem konieczne dlatego jest odwzorowanie hasła na inny ciąg. I tutaj pojawia się poważny problem. Jak to zrobić, by zmiana hasła lub zmiana w algorytmie nie pociągała za sobą konieczności poznania postaci jawnej hasła usera? W swoim algorytmie zauważyłem inny błąd logiczny wczoraj. Działa on gdy otrzymuje pozycję znaku wpisanego przez usera. Tylko skąd ma tak naprawdę wiedzieć czy znak, który wpisał user, jest oryginalnie w haśle czy nie, a jeśli tak to na jakiej tak naprawdę pozycji? Brakuje mu więc funkcji transkodowania znaku na pozycje w haśle i powinien zostać zmodyfikowany by mógł być prawidłowy. Dlatego w tej chwili jeśli chcemy faktycznie zastanowić się jak zrobić tę autoryzację musimy rozwiązać problem niezależności hasła od algorytmu. Lub inaczej to ujmując, znaleźć sposób na to, by móc zmieniać w dowolnej chwili hashe bez konieczności poznania jawnej postaci hasła. Dopóki więc Twój nie znajdzie metody na uniezależnienie się hasła od algorytmu, a w moim nie znajdzie się funkcja potrafiąca rozpoznać pozycję w haśle znaku podanego przez usera to oba, moim zdaniem, nie powinny być brane pod uwagę, ze względow bezpieczeństwa. Dlatego teraz skupmy się nie na otoczce jak sprawić by kod był nie do złamania, ale nad tym jak w sposób nie wymagający poznania hasła wprowadzić do algorytmu możliwość generowania skrótów gdy zmieniamy coś w środku. Innymi słowy musimy znaleźć "zastępcę" hasła, który będzie wyjściowym w razie zmian.
Jak to widzę by ominąć problem?
Zmiana hasła pociąga za sobą utworzenie sha2 (lub innego, którego jeszcze nie "łamią" ) każdej litery w haśle i wrzucenie gdzieś do bazy a potem postępowanie według algorytmu jakby nigdy nic. W razie konieczności zmiany czegoś w algorytmie generujemy nowe hashe dla usera na podstawie hasha każdej z liter nie bacząc wcale na znajomość hasła. A jak będzie ze sprawdzeniem? W zasadzie nawet wystarczyło by sprawdzenie czy hash litery przesłanej pokrywa się z hashem generowanym.
Wniosek: Nie ma sensu kodować jakichś zmian wielkich bo algorytm nie będzie nigdy w pełni niezależny od hasła i złamanie go będzie miało punkt krytyczny w miejscu zapisu znaków hasła, jeśli zechcemy się uniezależnić od jego znajomości co automatycznie poddaje w wątpliwość sens pisania niesamowicie skomplikowanych algorytmów. Bo po co mam przerzucać literę przez cały kod z hashami, tokenami i obciążać bazę generowaniem ich dla ogromu użytkowników co jakiś czas, skoro porównanie może nastąpić zaraz po użyciu funkcji hashującej znak na konkretnej pozycji? Czyli de facto wracamy do punktu początkowego. By to unaocznić rozrysuję drogę:
Zapis do bazy przy zmianie (tworzeniu) hasła: Litera hasła -> hash litery -> algorytm, token i sole -> hash litery po algorytmie
Zmiana algorytmu, soli lub tokena: hash litery -> zmieniony algorytm, sole lub token -> nowy hash liter
Porównanie: user podaje literę hasła -> algorytm, token i sole -> wyliczony hash -> porównanie z "hash litery po algorytmie"
Tyle że takie działanie jest kompletnie bezsensowne z prostej przyczyny: wystarczy złamać "hash litery" i algorytm leży. Inna sprawa, że wystarczy sprawdzić czy "hash litery" i "user podaje literę hasła" + funkcja hashująca dają to samo dry.gif Czyli sens algorytmu można rozwalić o kant d... i zawsze musimy znać jawna postać hasła lub hash jego liter gdy zamierzamy robić tokeny. Jest to więc bardziej sztuka dla sztuki niż poważne podejście do bezpieczeństwa.<br>Błagam, niech mnie ktoś wyprowadzi z błędu winksmiley.jpg
nexis
Cytat(thek @ 6.09.2009, 10:45:29 ) *
Wczoraj w chwili przerwy przejrzałem nasze wypowiedzi i zauważyłem jedną rzecz. Algorytm nad jakimi dumamy ma jedną, poważną (moim zdaniem) wadę. Działa jak należy gdy wywołamy procedurę zmiany hasła jawnie (tworzenie nowego przez usera czy "zapomniane hasło"). Jednak przy zmianie czegoś w algorytmie (tokeny czasowe, zmiana soli itp. ) będziemy leżeli i kwiczeli. Przy zmianie nikt nic nie będzie mógł autoryzować lub w skrajnym przypadku (jeśli prośba o podanie znaku z pozycji określonej wyskoczy przy logowaniu) nie zaloguje się. Błąd wynika z tego, że hashe porównawcze są generowane na podstawie istniejącego hasła. Każda więc zmiana pociąga za sobą konieczność generowania nowych hashy a więc i wymusza znajomość jawnej postaci hasła. Stąd też myślę, że konieczne byłoby uniezależnienie się algorytmu od tego typu luki. Moim zdaniem konieczne dlatego jest odwzorowanie hasła na inny ciąg. I tutaj pojawia się poważny problem. Jak to zrobić, by zmiana hasła lub zmiana w algorytmie nie pociągała za sobą konieczności poznania postaci jawnej hasła usera? W swoim algorytmie zauważyłem inny błąd logiczny wczoraj. Działa on gdy otrzymuje pozycję znaku wpisanego przez usera. Tylko skąd ma tak naprawdę wiedzieć czy znak, który wpisał user, jest oryginalnie w haśle czy nie, a jeśli tak to na jakiej tak naprawdę pozycji? Brakuje mu więc funkcji transkodowania znaku na pozycje w haśle i powinien zostać zmodyfikowany by mógł być prawidłowy. Dlatego w tej chwili jeśli chcemy faktycznie zastanowić się jak zrobić tę autoryzację musimy rozwiązać problem niezależności hasła od algorytmu. Lub inaczej to ujmując, znaleźć sposób na to, by móc zmieniać w dowolnej chwili hashe bez konieczności poznania jawnej postaci hasła. Dopóki więc Twój nie znajdzie metody na uniezależnienie się hasła od algorytmu, a w moim nie znajdzie się funkcja potrafiąca rozpoznać pozycję w haśle znaku podanego przez usera to oba, moim zdaniem, nie powinny być brane pod uwagę, ze względow bezpieczeństwa. Dlatego teraz skupmy się nie na otoczce jak sprawić by kod był nie do złamania, ale nad tym jak w sposób nie wymagający poznania hasła wprowadzić do algorytmu możliwość generowania skrótów gdy zmieniamy coś w środku. Innymi słowy musimy znaleźć "zastępcę" hasła, który będzie wyjściowym w razie zmian.
Jak to widzę by ominąć problem?
Zmiana hasła pociąga za sobą utworzenie sha2 (lub innego, którego jeszcze nie "łamią" ) każdej litery w haśle i wrzucenie gdzieś do bazy a potem postępowanie według algorytmu jakby nigdy nic. W razie konieczności zmiany czegoś w algorytmie generujemy nowe hashe dla usera na podstawie hasha każdej z liter nie bacząc wcale na znajomość hasła. A jak będzie ze sprawdzeniem? W zasadzie nawet wystarczyło by sprawdzenie czy hash litery przesłanej pokrywa się z hashem generowanym.
Wniosek: Nie ma sensu kodować jakichś zmian wielkich bo algorytm nie będzie nigdy w pełni niezależny od hasła i złamanie go będzie miało punkt krytyczny w miejscu zapisu znaków hasła, jeśli zechcemy się uniezależnić od jego znajomości co automatycznie poddaje w wątpliwość sens pisania niesamowicie skomplikowanych algorytmów. Bo po co mam przerzucać literę przez cały kod z hashami, tokenami i obciążać bazę generowaniem ich dla ogromu użytkowników co jakiś czas, skoro porównanie może nastąpić zaraz po użyciu funkcji hashującej znak na konkretnej pozycji? Czyli de facto wracamy do punktu początkowego. By to unaocznić rozrysuję drogę:
Zapis do bazy przy zmianie (tworzeniu) hasła: Litera hasła -> hash litery -> algorytm, token i sole -> hash litery po algorytmie
Zmiana algorytmu, soli lub tokena: hash litery -> zmieniony algorytm, sole lub token -> nowy hash liter
Porównanie: user podaje literę hasła -> algorytm, token i sole -> wyliczony hash -> porównanie z "hash litery po algorytmie"
Tyle że takie działanie jest kompletnie bezsensowne z prostej przyczyny: wystarczy złamać "hash litery" i algorytm leży. Inna sprawa, że wystarczy sprawdzić czy "hash litery" i "user podaje literę hasła" + funkcja hashująca dają to samo dry.gif Czyli sens algorytmu można rozwalić o kant d... i zawsze musimy znać jawna postać hasła lub hash jego liter gdy zamierzamy robić tokeny. Jest to więc bardziej sztuka dla sztuki niż poważne podejście do bezpieczeństwa.<br>Błagam, niech mnie ktoś wyprowadzi z błędu winksmiley.jpg

Cały wniosek brzmi dla mnie jak bełkot. O co ci tak naprawdę chodzi? Gdzie widzisz problem? Proszę podaj [b]konkretny[b] przykład, bo nic z twojej wypowiedzi póki co nie rozumiem.
thek
Wersja skrócona:
Problem: Algorytm się minimalnie zmienia. Pociąga to za sobą konieczność zmiany wszystkich hashy wszystkim użytkownikom bo inaczej każda autoryzacja za pomocą podania litery na pozycji X wywali błąd. Jak to zrealizujesz nie posiadając hasła w postaci, na podstawie której wygenerujesz nowe hashe dla każdej litery z osobna? Bo z hasha całego hasła takich danych nie uzyskasz w żaden sposób. Konieczne więc jest uniezależnienie się od znajomości tego hasła w postaci jawnej.
Taką zmianą mogło by być dodanie tokena losowego ważnego X godzin/dni. Po upłynięciu czasu konieczne jest ponowne generowanie hashy. Jak pobierzesz hasło usera i litery w nim by wygenerować nowe skróty? Odkodujesz z bazy hash hasła? winksmiley.jpg
Ja dałem propozycję zastosowania kodu pośredniego, który jest hashem każdego ze znaków w haśle. I to on byłby bazą dla obliczeń by nie sięgać do jawnej postaci.
Założenie hasła (aktualizacja hasła) -> Tworzymy hashe liter hasła metodą do tej pory nie złamaną (przykładowo sha-2) -> reszta algorytmu z solami itp., itd
Gdy następuje zmiana tokena, algorytmu czy czegokolwiek używamy już nie liter hasła ale tych hashy, dzięki czemu nie musimy znać jawnej postaci.
Weryfikacja polega na tym, że tą samą drogą traktujemy podany przez usera w formularzu znak hasła i porównujemy z wyliczonym i gdzieś przechowywanym hashem dla litery na danej pozycji.

Wniosek wysunąłem więc taki, że ta zabawa jest bezsensowna z prostej przyczyny: porównywać możemy na etapie już pierwszego hasha (ten od sha-2) i reszta to tylko sztuka dla sztuki. Zabawa w algorytm jaki my proponujemy ma bowiem tylko sens gdy hasło w bazie jest jawnie, gdyż inaczej nawet tych hashy nie mamy jak wygenerować biggrin.gif Bo skąd pobierzesz informację o tym jaka litera jest na jakiej pozycji do utworzenia hasha porównawczego?
Tylko po co w takim razie jeszcze dodatkowe algorytmy i tworzenie skrótów skoro hasło i tak mamy jawnie?
Dochodzimy więc do absurdu, w którym zwiększanie bezpieczeństwa, obniża je lub tworzy zupełnie zbędny kod.

Dlatego właśnie podstawowe pytanie dla Ciebie jako mojego partnera w dyskusji: Jak przewidujesz, i czy w ogóle masz zamiar, rozwiązać problem ewentualnej drobnej zmiany w algorytmie gdy masz już w bazie przynajmniej kilkuset userów? Jak w takiej sytuacji wygenerujesz im nowe hashe w sposób transparentny, bez zmuszania do ponownej zmiany hasła lub łamania ich haseł? Czy ustawisz w bazie flagę taką, że po zalogowaniu pierwszym, już po zmianie algorytmu, generuje im nowe hashe już zgodne z nowym algorytmem?
nexis
Ale po co miałbym kiedykolwiek zmieniać sól dla użytkownika? Jeśli zaszłaby taka potrzeba, to mamy wciąż taką możliwość przy autoryzacji, kiedy to użytkownik podaje nam hasło. Możemy wtedy sprawdzić czy podał prawidłowe hasło, a następnie wygenerować nową sól i zapisać nowy skrót w bazie danych.
thek
Chodzi mi o sytuacje gdy, przykładowo, zauważyłeś błąd w algorytmie i go musiałeś poprawić, lub jak już wspomniałem wprowadzić byś chciał pewne zmienne czasowo parametry (jakieś tokenki czy inne tego typu drobiazgi), które wymagały by okresowego dostępu do hasła. Zauważ, że tego typu sytuacje wymagają znajomości znaków hasła na każdej pozycji by wygenerować dla nich nowy skrót.
Na ten moment raz podane hasło generuje grupę hashy dla liter i jakakolwiek zmiana algorytmu (niekoniecznie soli użytkownika czy pozycji) sprawia, że hashe są nieprawidłowe. Jeśli zauważyłbyś w algorytmie lukę bezpieczeństwa to co byś zrobił by zmienić algorytm i wygenerować uzależnione od nowego algorytmu hashe? Na tę chwilę myślę, że musiałbyś ustawić flagę w bazie jakąś i czekać aż user zaloguje. Jeśli flaga jest na false to przechwyć jego hasło w postaci jawnej, odpal procedurę zmiany hashy, ustaw flagę na true i ok. Nie sądzę by inaczej się dało, bo przecież nie wyciągniesz hasła z hasha w bazie.
Stąd właśnie wspomniałem, że jeśli już by dochodziły naprawdę losowe rzeczy to konieczne jest przechowywanie informacji o chociażby skrótach znaków hasła gdzieś. Oczywiście tylko w sytuacji gdy taki wymóg jak zmienne tokeny jest konieczny, bo jak już powiedziałem to wprowadza przerost formy nad treścią już. Ale może się okazać, że w ten sposób jest realizowany dostęp do pewnych danych serwisu i niestety nie da się tego uniknąć.
nexis
Algorytm opracowuje się raz i dobrze. Cała jego idea polega właśnie na tym, że tylko użytkownik zna hasło, a w bazie trzymamy jedynie dane umożliwiające jego poprawną weryfikację, nie zaś jakąkolwiek postać, które umożliwia ponowne odczytanie. Idziesz w złym kierunku.
thek
Wiem, że algorytm powinien być napisany raz a dobrze, ale nie można wszystkiego przewidzieć. Bo nigdy zresztą sam nie wiesz gdzie ktoś wykryje lukę, która może się w Twoim algorytmie ujawnić. Dla przykładu... Ktoś znajdzie sposób na w miarę szybkie złamanie sha1, nawet posolone. Co wtedy robisz? Musisz przynajmniej funkcję hashująca na inną zmienić. A to wiąże się z ponownym przeliczeniem skrótów. Osobiście sam bym zarzucił "dodatkowy" ukryty hash. Powody są dwa: dublowanie informacji o haśle i to co napisałem wyżej, czyli bezsensowność tego rozwiązania w kwestii niepotrzebnego dokładania nadmiarowej pracy dla serwera, która i tak jest sztuką dla sztuki a nie poważnym zabezpieczaniem.
Pozostaje jednak problem... Co zrobić by się przed ewentualnym problemem konieczności zmiany czegoś w algorytmie zabezpieczyć. Znaczy jak i czy w ogóle ma sens ewentualna furtka dla admina by zmienić hashe userowi w określonym wypadku.
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.