Utrzymujesz istniejącą aplikację z ustaloną bazą użytkowników. Z czasem zdecydowano, że obecna technika haszowania haseł jest nieaktualna i wymaga aktualizacji. Ponadto, z powodów UX, nie chcesz, aby istniejący użytkownicy byli zmuszani do aktualizacji swojego hasła. Cała aktualizacja skrótu hasła musi odbywać się za ekranem.
Załóżmy „uproszczony” model bazy danych dla użytkowników, który zawiera:
- ID
- Hasło
Jak podchodzi się do rozwiązania takiego wymogu?
Moje obecne myśli to:
- utwórz nową metodę mieszania w odpowiedniej klasie
- zaktualizuj tabelę użytkowników w bazie danych, aby zawierała dodatkowe pole hasła
- Gdy użytkownik pomyślnie zaloguje się przy użyciu nieaktualnego skrótu hasła, wypełnij drugie pole hasła zaktualizowanym skrótem
Pozostawia mi to problem polegający na tym, że nie mogę rozsądnie rozróżnić między użytkownikami, którzy mają, a tymi, którzy nie zaktualizowali skrótu hasła, i dlatego będę zmuszony sprawdzić oba. To wydaje się okropnie wadliwe.
Co więcej, oznacza to w zasadzie, że stara technika haszująca może zostać zmuszona do pozostania na czas nieokreślony, dopóki każdy użytkownik nie zaktualizuje swojego hasła. Dopiero w tym momencie mogłem rozpocząć usuwanie starego testu mieszania i usunąć zbędne pole bazy danych.
Głównie szukam tutaj kilku wskazówek projektowych, ponieważ moje obecne „rozwiązanie” jest brudne, niekompletne, a co nie, ale jeśli rzeczywisty kod jest wymagany do opisania możliwego rozwiązania, możesz użyć dowolnego języka.
źródło
Odpowiedzi:
Sugerowałbym dodanie nowego pola, „hash_method”, gdzie być może 1 oznacza starą metodę, a 2 oznacza nową metodę.
Rozsądnie mówiąc, jeśli zależy ci na tego rodzaju rzeczach, a Twoja aplikacja jest stosunkowo długa (co już najwyraźniej już jest), prawdopodobnie stanie się to ponownie, ponieważ kryptografia i bezpieczeństwo informacji to tak ewoluująca, raczej nieprzewidywalna dziedzina. Był czas, kiedy zwykłe uruchamianie przez MD5 było standardem, jeśli w ogóle użyto haszowania! Wtedy można by pomyśleć, że powinni użyć SHA1, a teraz jest solenie, globalna sól + pojedyncza losowa sól, SHA3, różne metody generowania liczb losowych gotowych na krypto ... to nie będzie po prostu „zatrzymywać”, więc możesz napraw to w rozszerzalny, powtarzalny sposób.
Powiedzmy teraz, że masz coś takiego (mam nadzieję, że w pseudo-javascript):
Teraz, gdy zdajesz sobie sprawę, że istnieje lepsza metoda, wystarczy podać drobne zmiany:
Przy tworzeniu tej odpowiedzi nie ucierpieli tajni agenci ani programiści.
źródło
newHash(oldHash, salt)
lubnewHash(password, salt)
Jeśli zależy ci na jak najszybszym wdrożeniu nowego schematu haszowania dla wszystkich użytkowników (np. Ponieważ stary jest naprawdę niepewny), istnieje sposób na natychmiastową „migrację” każdego hasła.
Chodzi przede wszystkim o haszowanie skrótu . Zamiast czekać na podanie przez użytkowników istniejącego hasła (
p
) przy następnym logowaniu, od razu używasz nowego algorytmu mieszającego (H2
) na istniejącym haszu już wygenerowanym przez stary algorytm (H1
):Po wykonaniu tej konwersji nadal możesz doskonale zweryfikować hasło; wystarczy wykonać obliczenia
H2(H1(p'))
zamiast poprzedniego,H1(p')
gdy użytkownik próbuje zalogować się przy użyciu hasłap'
.Teoretycznie, technika ta może być stosowana na wielu (migracji
H3
,H4
etc.). W praktyce chciałbyś pozbyć się starej funkcji skrótu, zarówno ze względu na wydajność, jak i czytelność. Na szczęście jest to dość łatwe: po kolejnym udanym logowaniu po prostu oblicz nowy hash hasła użytkownika i zastąp go istniejącym hash-a-hash:Będziesz także potrzebował dodatkowej kolumny, aby zapamiętać, jaki hash przechowujesz: hasło lub stary skrót. W niefortunnym przypadku wycieku bazy danych ta kolumna nie powinna ułatwiać pracy crackera; niezależnie od jego wartości, atakujący nadal musiałby odwrócić bezpieczny
H2
algorytm zamiast staregoH1
.źródło
Twoje rozwiązanie (dodatkowa kolumna w bazie danych) jest całkowicie do przyjęcia. Jedynym problemem jest ten, o którym już wspomniałeś: stary skrót jest nadal używany dla użytkowników, którzy nie uwierzytelnili się od czasu zmiany.
Aby uniknąć tej sytuacji, możesz poczekać, aż najbardziej aktywni użytkownicy przejdą na nowy algorytm mieszania, a następnie:
Usuń konta użytkowników, którzy nie uwierzytelniają się zbyt długo. Nie ma nic złego w usuwaniu konta użytkownika, który nigdy nie odwiedził witryny przez trzy lata.
Wyślij wiadomość e-mail do pozostałych użytkowników, którzy nie uwierzytelnili się przez jakiś czas, informując, że mogą być zainteresowani czymś nowym. Pomoże to jeszcze bardziej zmniejszyć liczbę kont korzystających ze starszego skrótu.
Uważaj: jeśli masz opcję bez spamu, użytkownicy mogą sprawdzać w Twojej witrynie, nie wysyłaj wiadomości e-mail do użytkowników, którzy ją sprawdzili.
Wreszcie, kilka tygodni po kroku 2, zniszcz hasło użytkowników, którzy nadal korzystają ze starej techniki. Kiedy i jeśli spróbują się uwierzytelnić, zobaczą, że ich hasło jest nieprawidłowe; jeśli nadal są zainteresowani twoją usługą, mogą ją zresetować.
źródło
Prawdopodobnie nigdy nie będziesz mieć więcej niż kilka typów skrótów, więc możesz to rozwiązać bez rozszerzania bazy danych.
Jeśli metody mają różne długości skrótów, a długość skrótu każdej metody jest stała (powiedzmy, przejście z md5 na hmac-sha1), możesz odróżnić metodę od długości skrótu. Jeśli mają taką samą długość, możesz najpierw obliczyć skrót za pomocą nowej metody, a następnie starej metody, jeśli pierwszy test się nie powiedzie. Jeśli masz pole (niepokazane) informujące, kiedy użytkownik był ostatnio aktualizowany / tworzony, możesz użyć go jako wskaźnika dla której metody użyć.
źródło
Zrobiłem coś takiego i jest sposób, aby stwierdzić, czy jest to nowy skrót ORAZ uczynić go jeszcze bardziej bezpiecznym. Sądzę, że bezpieczniejsze jest dla ciebie dobre, jeśli poświęcasz czas na aktualizację swojego skrótu ;-)
Dodaj nową kolumnę do tabeli DB o nazwie „sól” i używaj jej jako soli generowanej losowo przez użytkownika. (prawie zapobiega atakom na tęczowe stoły)
W ten sposób, jeśli moje hasło to „pass123”, a losowa sól to 3333, moim nowym hasłem będzie skrót „pass1233333”.
Jeśli użytkownik ma sól, wiesz, że to nowy skrót. Jeśli sól użytkownika jest zerowa, wiesz, że to stary skrót.
źródło
Bez względu na to, jak dobra jest Twoja strategia migracji, jeśli baza danych została już skradziona (i nie można negatywnie udowodnić, że tak się nigdy nie stało), hasła przechowywane z niezabezpieczonymi funkcjami skrótu mogą już zostać naruszone. Jedynym ograniczeniem tego jest wymaganie od użytkowników zmiany haseł.
Nie jest to problem, który można rozwiązać (tylko) przez napisanie kodu. Rozwiązaniem jest informowanie użytkowników i klientów o zagrożeniach, na jakie zostali narażeni. Gdy tylko zechcesz być na ten temat otwarty, możesz przeprowadzić migrację, po prostu resetując hasło każdego użytkownika, ponieważ jest to najłatwiejsze i najbezpieczniejsze rozwiązanie. Wszystkie alternatywy naprawdę polegają na ukrywaniu tego, że spieprzyłeś.
źródło