Jak przechowywać hasła

0

Takie pytanie. Mam aplikację webową na serwerze hostingowym. Na tym samym serwere jest baza danych. Aplikacja łączy się za pomocą webApi z różnymi zewnętrznymi serwisami. Klienci logują się do systemu stosując indywidualne hasła. Obsługę haseł klientów mam załatwioną. Pytanie: w jaki sposób i gdzie przechowywać hasła i inne access tokeny do wszystkich WebApi z którymi łączy się aplikacja? Przecież nie każę przy każdym logowaniu podawać klientowi 10 haseł. Wpisać na sztywno do kodu głupio i niepraktycznie. Jedyne co mi przychodzi do głowy to jakoś je kodować i dekodować w programie i w zakodowanej postaci zapisywać w bazie. Co myślicie?

0

przecież hasła zwykle przechowuje się w bazie jako hash md5
Dekodować hasła nie musisz, baza danych nie powinna o nim wiedzieć jakie ono jest dokładnie, wystarczy ten hash, i w przy logowaniu porównujesz mdEncode(haselkoString) z tym z bazy

2

Takie rzeczy musisz szyfrować i w formie zaszyfrowanej trzymać w bazie. Nie znam innego sposobu. Klucze przechowywać w configu lub jako certy. I tutaj pojawia się najgorsza kwestia, bo jak będzie włamanie do bazy do jeszcze ok, ale jak się dostanie do plików to macie totalny kataklizm. Wasz devops musi być dobry no i sam kod powinien mieć porządne review i mieć cykliczne audyty bezpieczeństwa.

1

Do 3rd party API powinieneś mieć tylko jedno konto/klucz (ewentualnie jedno per środowisko) per integracja. Twoja aplikacja powinna być swego rodzaju proxy do tych serwisów.

1
iksde napisał(a):

Do 3rd party API powinieneś mieć tylko jedno konto/klucz (ewentualnie jedno per środowisko) per integracja. Twoja aplikacja powinna być swego rodzaju proxy do tych serwisów.

Podam ci przykład, kiedy to co gadasz to brednie :) Serwis korzysta z google driva, każdy user może sobie podpiąć taki dysk indywidualnie, bo coś tam ma ta jego apka zapisywać, a to oznacza że KAŻDY user ma INDYWIDUALNY TOKEN LUB ZAPISANE HASŁO I LOGIN do swojego dysku.

Edit, dodam tylko, że to nie jest wcale jakieś dziwne, bo pół roku temu przez kilka miesięcy pracowałem nad takim serwisem, który integrował w sobie kilka innych serwisów, tak by user z jednego miejsca zarządzał kontami z kilku zupełnie innych stron ale robiących to samo. Tam musieliśmy zapisywać klucze, które userzy generowali w tych zewnętrznych serwisach.

0
mr_jaro napisał(a):
iksde napisał(a):

Do 3rd party API powinieneś mieć tylko jedno konto/klucz (ewentualnie jedno per środowisko) per integracja. Twoja aplikacja powinna być swego rodzaju proxy do tych serwisów.

Podam ci przykład, kiedy to co gadasz to brednie :) Serwis korzysta z google driva, każdy user może sobie podpiąć taki dysk indywidualnie, bo coś tam ma ta jego apka zapisywać, a to oznacza że KAŻDY user ma INDYWIDUALNY TOKEN LUB ZAPISANE HASŁO I LOGIN do swojego dysku.

Edit, dodam tylko, że to nie jest wcale jakieś dziwne, bo pół roku temu przez kilka miesięcy pracowałem nad takim serwisem, który integrował w sobie kilka innych serwisów, tak by user z jednego miejsca zarządzał kontami z kilku zupełnie innych stron ale robiących to samo. Tam musieliśmy zapisywać klucze, które userzy generowali w tych zewnętrznych serwisach.

A czy w takim przypadku (google drive) nie powinno to się odbyć tak, że użytkownik przekazuje aplikacji uprawnienia do swojego dysku/folderu? Oczywiście nie każda apka na coś takiego pozwoli, ale jeśli można to chyba tak by było lepiej :D

Opcja nr 2 - aplikacja ma swojego google drive'a, którego udostępnia użytkownikom i przy okazji zarządza uprawnieniami. Robiłem coś podobnego, tylko zamiast gdrive był Sharepoint, nawet spoko działało.

Pewnie można wymyślić scenariusze, gdzie nie da się tego zastosować, ale może akurat OP to wystarczy ;)

0

@iksde: przekazuje ale nadal ty w bazie musisz zapisać otrzymany klucz. A sama udzielenie uprawnień to rzadkość. Google i fb tak, ale inne nawet z sektora finansowego, nie maja czegoś takiego ;)

edit. oj uwierz, że opcja numer 2 jest możliwa w dużo mniej niż 1% przypadkach :D

0

Dziękuję za burzliwą dyskusję pod moim pytaniem, zwłaszcza @mr_jaro .Wydaje się więc, że potrzebne jest trzymanie w bazie zaszyfrowanych haseł. Pytanie gdzie trzymać klucze szyfrujące. A może zrobić coś takiego że za klucz robiłoby hasło użytkownika podawane przy logowaniu (ewentualnie po zhaszowaniu)? Wtedy unikniemy sytuacji, że klucze są przechowywane w kodzie/configu na serwerze. Tak myślę, że to by się mogło fajnie sprawdzić gdyby klient korzystający z zestawu haseł zewnętrznych był jeden. Jeśli w ramach firmy, korzystającej z tego samego zestawu haseł zewnętrznych jest wielu klientów, trzeba by robić jakąś formę dodatkowego logowania (podawania secret codu - takiego samego dla wszystkich użytkowników z jednej firmy). Ale dzięki temu nie będę miał na serwerze równocześnie zaszyfrowanych haseł i kluczy. Co myślicie?

0

jak będziesz szyfrował hashem to atakujący będzie miał wszystko na tacy gdy się dostanie do bazy. Za to gdy trzymasz klucze w plikach to gdy się dostanie tylko do bazy to nadal nic nie uzyska, a gdy się dostanie do plików to i tak do bazy się dostanie.

0

@mr_jaro No tak. Masz rację, ale to szczegół techniczny. Do szyfrowania/deszyfrowania można użyć innego rodzaju hashowania (czy przetwarzania hasła klienta na klucz do szyfrowania). Chodzi mi o samą ideę, dzięki której w bazie przechowywać będę hashe haseł klienta oraz zaszyfrowane hasła i loginy do serwisów zewnętrznych, a klucze do ich szyfrowania nie będą nigdzie przechowywane, bo będę je generował na podstawie hasła klienta w momencie gdy będzie się on logował. W momencie włamania, nawet gdy ktoś zdekompiluje mój kod, znajdzie jedynie metodę którą przetwarzam hasło klienta na klucz a nie sam klucz. Daj proszę znać czy widzisz jakieś haczyki, bo ja mam wrażenie że znalazłem graala.

0
  1. user zmienia hasło do konta u ciebie i nagle nie ma jak odszyfrować zapisanych haseł do zewnętrznych usług
  2. atakujący włamuje się na serwer, pobiera sobie kod, pobiera sobie bazę, odpala go u siebie lub, znajduje algorytm i ma dostep do wszystkich haseł zapisanych w bazie - brawo sprawiłeś, że 15 minut dłużej walczył by mieć wszystkie dane w plain text :)
0

@ccwr Wiesz, doskonale zdaję sobie sprawę, że nie jest to rozwiązanie dobre, ani do końca bezpieczne, ale jeśli już muszę trzymać w bazie zaszyfrowane hasła do serwisów to na pewno jest ono lepsze niż przechowywanie kluczy w pliku czy w kodzie.

0

Mam taki pomysł:

  • hasła do twojego serwisu przechowujesz zahaszowane,
  • hasła do serwisów zewnętrznych przechowujesz w formie zaszyfrowanej, przy czym elementem klucza szyfrującego jest hasło do twojego serwisu w formie otwartej.

Klient logując się, podaje hasło, system porównuje jego hasz, a później dekryptuje hasła zewnętrzne.

Włamywacz musi zdehaszować hasła wewnętrzne, żeby móc zdekryptować hasła zewnętrzne.

Tylko nie wiem, czy połączenie tych dwóch metod, potencjalnie nie osłabi... ich obu. Bo masz tu kilka różnych plików w oparciu o których możesz jakoś wnioskować o zhaszowanym haśle klienta.

0

Sugerowanie zeby uzywac md5 kiedy 8 znakowe sha juz zaczyna byc bezuzyteczne ...

title

0

Nie żadne MD5 (kolizje MD5 da się aktualnie generować poniżej jednej sekundy) ani hashe bezpośrednio tylko rób to co wszyscy w krypto polecają: PBKDF2, w bazie zapisujesz 16 losowych (użyj dobrej funkcji losującej inaczej cała reszta o kant d...) bajtów soli i hash. Wybierz odpowiednio dużą liczbę iteracji (nim więcej tym lepiej i wolniej - nim wolniej tym atakującemu więcej zajmie znalezienie klucza/kolizji).

Ale tak jak ktoś wyżej wspomniał - jak ktoś ma dostęp do bazy i kodu serwera to Ci nie pomoże bo można hasło przechwycić już na poziomie przeglądarki.

Generalnie to rób backupy i zapisuj offline bo wszystko się aktualnie da zepsuć, a jak nie to poczekaj pare miesięcy i ktoś coś wymyśli.

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