Pisanie komunikatora - problem 2, czyli bezpieczeństwo

0

Cześć, mam kolejny problem z pisaniem komunikatora, a mianowicie chodzi o bezpieczeństwo.

Mam kilka opcji, jak jak rozwiązać komunikację z serwerem.

  1. Klient łączy się z programem na serwerze, wysyła do niego odpowiedni pakiet i otrzymuje login i hasło(właściwie cały connectionstring) do serwera. Klient wykonuje zapytania na serwerze bezpośrednio.

  2. Klient łączy się z programem na serwerze, wysyła do niego odpowiedni pakiet, otrzymuje login i hasło(connectionstring) do serwera. Zapytania są wykonywane tak, że klient wysyła zapytanie do programu na serwerze, program wykonuje zapytanie w bazie i zwraca wynik klientowi

  3. Klient informacje o połączeniu z serwerem(connectionstring) ma wpisane na stałe. Zapytania wykonywane są bezpośrednio

  4. Klient informacje o połączeniu z serwerem(connectionstring) ma wpisane na stałe. Zapytania wykonywane są za pomocą programu na serwerze(tak jak w punkcie drugim).

Moje pytanie: Która z tych metod będzie najbardziej optymalna, a która najbezpieczniejsza i dlaczego. Oczywiście zanim pakiet zostanie gdziekolwiek wysłany będzie szyfrowany jakimś DESem, czy czymś innym.

0

Po co klientowi connectionstring do serwera? Skoro na serwerze jest program, ktory umie obslugiwac żądania klienta, to nie moze mu wyslac odpowiednich danych z bazy, skoro i tak go jakos autoryzuje ('odpowiedni pakiet')?

0

Hasła nigdy nie przesyłaj. I na co jakiś connectionstring? Co on ma dodatkowego zawierać? Zależnie od tego, jak chcesz zakręcić autoryzację, sensowne są dwie metody.

  1. Klient łączy się z serwerem, wysyła mu swój login i skrót (na przykład MD5) z hasła. Serwer sprawdza czy dla danego loginu, skrót jest właściwy i albo klienta odłącza (lub nie reaguje na niego), albo zaczyna obsługiwać jego zapytania.

  2. Klient łączy się z serwerem, a ten mu odpowiada krótkim, losowym ciągiem znaków. Klient wysyła swój login oraz skrót (na przykład MD5) ze stringu hasło+ciąg losowy. Serwer sprawdza czy dla danego loginu skrót jest właściwy i albo klienta odłącza (lub nie reaguje na niego), albo zaczyna obsługiwać jego zapytania.

Poczytaj o już zaimplementowanych w różnych protokołach metodach autoryzacji - po co wymyślać coś od zera, jak z bezpiecznych metod inne usługi korzystają już dawno?

0

Po to mi connection string, że nadal nie wiem jeszcze, czy lepiej wykonywać operacje na bazie bezpośrednio klientem, czy za pośrednictwem programu na serwerze.

Johnny mówi, że program na serwerze ma obsługiwać. Ale tu się pojawia utrudnienie związane np. z wyszukiwaniem innych użytkowników, lub importem/eksportem listy kontaktowej do serwera. A także prostsze rzeczy typu zmiana statusu użytkownika(aktualnego opisu, czy też jak w GG, czy widoczny, niewidoczny itd) - te informacje też muszą być zapisywane w bazie.

0

Obslugiwanie klientem ma jedna wade - nigdy nie wiesz czy to Twoj klient pyta o connection string... To tak jakbys wchodzac do sklepu dostawal klucze do magazynu, zeby sobie samemu wybrac to co chcesz kupic. W zaden sensowny sposob nie jestes w stanie w takiej sytuacji zabronic komus dostepu/zmiany nieswoich danych. A nawet jesli sie postarasz i zrobisz np. odpowiednie procedury skladowane, to co jesli do aplikacji dojdzie jakas nowa logika? Nie wszystko dotyczy bazy danych. Kazesz wszystkim aktualizowac klientow, bo zmienilo sie cos w bazie?

Sposob obslugi autoryzacji podal Ci juz Szczawik. Nie rozumiem podanego przez Ciebie utrudnienia. Dla mnie to raczej ulatwienie, ze serwer zajmuje sie zapodawaniem wszystkich danych.

0

Czyli najlepiej robić tak, że wysyłać do programu na serwerze odpowiednie zapytania SQL, potem ten program, będzie pracował na bazie i odsyłał wyniki do klienta, tak?

A utrudnienie jest takie, że po prostu będę musiał oprogramować kilka nowych rzeczy, a nie np. posługiwać się ADO(z poziomu klienta ;))

0

Nie SQL. Jak bedziesz wysylal czystego sql i tak po prostu beztrosko sobie go wywolywal to Twoj komunikator bedzie mial ogromiasta dziure w bezpieczenstwie na dzien dobry. Traktuj serwer jako przekaznik. Klient zawsze PROSI serwer o udostepnienie informacji.
Przykladowy scenariusz wyglada tak:

  • wysylasz komunikat 'lognij mnie' i wraz z nim login i skrot hasla (np. MD5)
  • serwer odsyla: 'poprawnie zalogowany, Twoj token to k4jh56jh345g76jh7'
  • wysylasz komunikat 'daj mi liste opisow moich znajomych' i do komunikatu zalaczasz token (coby serwer Cie rozpoznal) i liste Twoich znajomych - bo nie bardzo jest sens, zeby serwer ja pamietal.
  • serwer odpowiada: 'Zdzisiu Trabka ma opis: hej ho, Celinka ma opis: nie ma mnie, ...'

Mozesz trzymac otwarte polaczenie do serwera, wtedy nie trzeba tokenow. Plus jest taki, ze trudniej przejac otwarte polaczenie niz token. Minus taki, ze po rozlaczeniu znowu trzeba wyslac do serwera komunikat o ponownym zalogowaniu.

Cala rola serwera polega na obsludze przychodzacych żądań (odpowiedzi, bądź odmowy odpowiedzi, bo np. token nieznany) i wywolywaniu odpowiednich procedur na bazie, czy tam silniku komunikatora.

Duuuuuzym plusem jest latwiejsza mozliwosc zmian. Zalozmy, ze z roznych przyczyn zmienia sie wersja bazy danych albo trzeba sie przeprowadzic na inna (szybsza, lepsza, bo mysql wysiada juz przy takiej ilosci). Wtedy w KAZDYM kliencie musisz pozmieniac zapytania SQL, bo przeciez kazdy klient je zna. Co oznacza, ze przy zmianie i zmuszeniu polowy ludkow do aktualizacji komunikatora, drugiej polowie juz nie dziala.

Nawet jak zmiany nie beda drastyczne, to oszczedzasz sobie nerwow na kompatybilnosc wsteczna w duzym zakresie. Klienta nie interesuje czy wyszukiwarka kontaktow dziala w oparciu o sztuczna inteligencje, google'a czy zwykle liniowe wyszukiwanie. On tylko wysyla komunikat do serwera 'znajdz mi tego kogos' i juz.

0

OK, dzięki wielkie za tą odpowiedź. Teraz już wiem, jak się za to zabrać. Jeszcze później pewnie będę miał problemy z socketami, ale to później ;)

0
johny_bravo napisał(a)
  • serwer odsyla: 'poprawnie zalogowany, Twoj token to k4jh56jh345g76jh7'
  • wysylasz komunikat 'daj mi liste opisow moich znajomych' i do komunikatu zalaczasz token (coby serwer Cie rozpoznal) i liste Twoich znajomych - bo nie bardzo jest sens, zeby serwer ja pamietal.

Właściwie zawsze serwer przechowuje token, a nie klient. Jeśli serwer jest wielowątkowy, to po prostu w zmiennej wątku zapisuje token klienta, którego połączenie jest obsługiwane w danym wątku. Po co? Dla serwera to niewielki wysiłek, a jednocześnie ta sama zmienna często jest wykorzystywana do następującej pracy:

  1. Klient (K) -> Serwer (S): połączenie
  2. K -> S: podaj mi listę moich znajomych
  3. S: token jest pusty
  4. S -> K: nie autoryzowałeś się jeszcze
  5. K -> S: mój login, mój skrót hasła
  6. S: dane się zgadzają - ustawiam token
  7. S -> K: jesteś autoryzowany
  8. K -> S: podaj mi listę moich znajomych
  9. S -> K: twoi znajomi to..

Zauważ, że skoro token nie jest przesyłany, nikt się pod niego nie podszyje. Skoro klient nie przesyła tokena, on też pod nikogo się nie podszyje.

0

Z przesylaniem tokena chodzilo mi bardziej przy usprawnieniu dzialania klienta - przy rozlaczeniu, trzeba sie ponownie logowac. Chociaz chyba lepiej, zeby klient zapamietywal na czas dzialania hash i wysylal ponownie.

Swoja droga jak zabezpieczyc sie z kolei przed przechwycenie hasha? Polaczenie szyfrowane?

0

Bardzo prosto: nie przesyłać hash'a hasła tylko hash hasła i ciągu losowego, przysłanego przez serwer przy połączeniu.

K -> S: połączenie
S -> K: dzisiejsze połączenie sponsoruje literka 'A' oraz liczba '1234'
K -> S: mój login, hash(moje hasło + 'A' + '1234')
Intruz (I): przechwycenie hash(moje hasło + 'A' + '1234')

I -> S: połączenie
S -> I: dzisiejsze połączenie sponsoruje literka 'B' oraz liczba '2345'
I -> S: login K, hash(moje hasło + 'A' + '1234')
S -> I: złe hasło!

Intruz (z definicji funkcji hashujących) nie da rady poznać (w sensownym czasie) treści hasła o przechwyconej zawartości; a właśnie je, a nie hash, potrzebuje by móc się podszywać. Oczywiście szyfrowanie połączenia jest jak najbardziej zalecane.

Klient powinien znać tylko swój login i hasła, resztę może wyliczyć na bieżąco.

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