REST web Service authentication token implementation

Implementuję usługę REST web przy użyciu C# , która będzie hostowana na Azure jako usługa w chmurze. Ponieważ jest to usługa REST, jest bezpaństwowa i dlatego nie ma plików cookie ani stanów sesji.

Do usługi internetowej można uzyskać dostęp tylko przez HTTPS (certyfikat dostarczany przez StartSSL.com).

Po pomyślnym zalogowaniu się do Serwisu Użytkownik otrzyma token bezpieczeństwa. Token ten zapewni uwierzytelnianie w przyszłej komunikacji.

Token będzie zawierał timestamp, userid i adres ip klienta.

Cała komunikacja będzie się odbywać tylko przez HTTPS, więc nie martwię się o to, że token zostanie przechwycony i użyty w atakach replay; token i tak będzie miał wygaśnięcie.

Ponieważ jest to usługa publiczna, obawiam się jednak, że ktoś może zarejestrować się w serwisie, zalogować się, a następnie zmodyfikować token, który otrzymuje, aby uzyskać dostęp do kont innych użytkowników.

Zastanawiam się jak najlepiej zabezpieczyć zawartość token, a także sprawdzić, czy nie został naruszony.

Planuję zrobić co następuje, aby zabezpieczyć token:

Klient pomyślnie loguje się do serwisu i serwis robi:

  1. Wygeneruj losową wartość i hashuj ją SHA256 1000 razy.
  2. Wygeneruj jednorazowy klucz sesji z klucza prywatnego + zahaszowana losowa wartość.
  3. Haszuj klucz sesji za pomocą SHA256 1000 razy, a następnie użyj go do zaszyfrowania tokenu
  4. Użyj klucza prywatnego, aby podpisać zaszyfrowany token przy użyciu RSA.
  5. wysyła zaszyfrowany token + podpis + zaszyfrowaną losową wartość do Klienta w niezaszyfrowanym pakiecie JSON.

Gdy klient wywołuje usługę, wysyła do usługi zaszyfrowany token i podpis w niezaszyfrowanym pakiecie JSON. Usługa będzie

  1. Odtwórz klucz sesji z klucza prywatnego + zahaszowana losowa wartość
  2. Użyj klucza prywatnego, aby zweryfikować podpis
  3. użyj zaszyfrowanej sesji klucz do odszyfrowania tokena
  4. sprawdź, czy token nie wygasł
  5. Kontynuuj żądaną operację...

Nie znam się na szyfrowaniu więc mam kilka pytań:

    Czy to wystarczy, czy przesada?
  1. czytałem, że aby wykryć manipulację, powinienem dołączyć HMAC do tokena. Czy ponieważ podpisuję się kluczem prywatnym, nadal potrzebuję HMAC?
  2. Czy powinienem używać Rijndael zamiast RSA?
  3. jeśli Rijndael jest preferowany, czy wygenerowany IV jest wymagany do odszyfrowania? tj. czy mogę go wyrzucić, czy muszę wysłać zaszyfrowany token? np. zaszyfrowany Token + HMAC + IV + hashed losowa wartość.

Ponieważ cała komunikacja odbywa się przez HTTPS, niezaszyfrowany pakiet JSON nie jest tak naprawdę niezaszyfrowany, dopóki nie dotrze do klienta.

Również mogę chcieć ponownie zaimplementować usługę w PHP później, więc to wszystko musi być wykonalne również w PHP.

Dzięki za pomoc

Author: There is no spoon, 2013-03-19

1 answers

Naprawdę przesadzasz z tym tokenem. Prawdę mówiąc, najlepsze zabezpieczenia tokenów opierają się na losowości, a dokładniej nieprzewidywalności. Najlepsze żetony są całkowicie losowe. Masz rację, że obawa polega na tym, że użytkownik zmodyfikuje swój token i użyje go do uzyskania dostępu do kont innych osób. Jest to częsty atak znany jako " kradzież sesji."Ten atak jest prawie niemożliwy, gdy tokeny są losowo generowane i wygasają po stronie serwera. Korzystanie z informacji użytkownika takie jak IP i / lub znacznik czasu jest złą praktyką, ponieważ poprawia przewidywalność. Zrobiłem atak w college ' u, który z powodzeniem odgadł aktywne tokeny, które były oparte na znacznikach czasu serwera w mikrosekundach. Autor aplikacji myślał, że mikrosekundy zmienią się na tyle szybko, że będą nieprzewidywalne, ale tak nie było.

Należy pamiętać, że gdy użytkownicy znajdują się za serwerami proxy, proxy czasami wyświetla ich żądania SSL w postaci zwykłego tekstu (ze względów bezpieczeństwa, wiele serwerów proxy przeprowadzi głęboką inspekcję pakietów). Z tego powodu dobrze jest, że wygasają sesje. Jeśli tego nie zrobisz, Twoi użytkownicy będą podatni na atak taki jak ten, a także możliwe XSS i CSRF.

RSA lub Rijndael powinny być wystarczające, pod warunkiem rozsądnej długości klucza. Ponadto powinieneś użyć HMAC z tokenem, aby zapobiec manipulowaniu, nawet jeśli go podpisujesz. Teoretycznie byłoby to zbędne, ponieważ podpisujesz się kluczem prywatnym. Jednak HMAC jest bardzo dobrze przetestowane, a twoja implementacja mechanizmu podpisywania może być wadliwa. Z tego powodu lepiej jest używać HMAC. Zdziwiłbyś się, jak wiele wdrożeń zabezpieczeń typu "roll your own" ma wady, które prowadzą do kompromisu.

Wydajesz się dość bystry w kwestii bezpieczeństwa. Tak trzymać! Potrzebujemy bardziej świadomych bezpieczeństwa deweloperów na tym świecie.

EDIT:

Uważa się za bezpieczne dołączenie znaczników czasu/identyfikatorów użytkowników do tokena, o ile są one zaszyfrowane za pomocą silnego symetryczny tajny klucz (jak AES, Blowfish, itp.), który posiada tylko serwer i tak długo, jak token Zawiera z nim zabezpieczony przed manipulacją hash, taki jak HMAC, który jest zaszyfrowany tajnym kluczem wraz z identyfikatorem użytkownika/znacznikiem czasu. Hash gwarantuje integralność, a szyfrowanie gwarantuje poufność.

Jeśli nie włączysz HMAC (lub innego hasha) do szyfrowania, użytkownicy mogą manipulować zaszyfrowanym tokenem i kazać mu odszyfrować do czegoś ważne. Zrobiłem atak na serwer, w którym identyfikator użytkownika i znacznik czasu zostały zaszyfrowane i używane jako token bez hash. Zmieniając jeden losowy znak w łańcuchu, byłem w stanie zmienić mój identyfikator użytkownika z czegoś takiego jak 58762 do 58531. Chociaż nie mogłem wybrać "nowego" identyfikatora użytkownika, mogłem uzyskać dostęp do konta innej osoby (to było w Akademii, w ramach kursu).

Alternatywą jest użycie całkowicie losowej wartości tokenu i mapowanie jej po stronie serwera do przechowywanego użytkownika ID / znacznik czasu (który pozostaje po stronie serwera i tym samym jest poza kontrolą klientów). Wymaga to trochę więcej pamięci i mocy obliczeniowej, ale jest bezpieczniejsze. To jest decyzja, którą będziesz musiał podjąć indywidualnie.

Jeśli chodzi o ponowne użycie / wyprowadzenie kluczy z IV i innych kluczy, zwykle jest to w porządku, pod warunkiem, że klucze są ważne tylko przez krótki okres czasu. Matematycznie jest mało prawdopodobne, że ktoś może je złamać. Jest to jednak możliwe. Jeśli chcesz być paranoikiem trasa (co zwykle robię), generować wszystkie nowe klucze losowo.

 25
Author: Freedom_Ben,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-26 16:51:34