Właśnie rozpocząłem rozwój mojego pierwszego API REST w .NET. Ponieważ będzie to bezpaństwowcem użyję tokeny do uwierzytelniania:Autoryzacja tokenów REST API
Podstawowa idea (System.Security.Cryptography):
- AES do szyfrowania + HMACSHA256 integralności
- dane symboliczne obiekt składać się będzie z właściwości: nazwa, data wydania i Timeout
- baza danych będzie posiadać nazwę użytkownika, hasło i mieszany HMAC hash
Login:
- sprawdzić, czy poświadczenia są ważne (nazwa użytkownika, porównaj zaszyfrowany hasło Wartość dB)
- jeśli jest prawdziwa, szyfrowania danych obiektów
- użycie HMAC na wygenerowane żeton i przechowywać go do bazy
- powrócić żeton (bez HMAC), aby użytkownik (cookie/string)
Zapytanie do metody, która wymaga uwierzytelnienia:
- użytkownik wysyła żeton z każdego żądania
- token rozszyfrowanej
- jeśli jest wygasł, błąd
- jeżeli nie upłynął użycie HMAC i porównać login + wygenerowany hash z db wartości
- jeśli db sprawdź poprawny, użytkownik jest uwierzytelniony
Sposób, w jaki to widzę, ma następujące zalety:
- nawet jeśli db jest comprosmised, że nie zawiera on rzeczywisty znacznik (hash nie można odwrócić ...)
- nawet jeśli atakujący ma żeton, nie może zwiększyć upływie pól aktualizujących ponieważ data ważności jest w token sam w sobie
Teraz po pierwsze zastanawiam się, czy to w ogóle dobre podejście. Poza tym nadal nie wiedziałem, gdzie przechowywać klucze AES i SHA256 na serwerze (czy powinienem je po prostu skasować? Jeśli umieściłem je w web.config lub użyłem klucza maszynowego to mam problem w przypadku ładuj zbalansowane serwery, ...).
I wreszcie, gdzie mam przechowywać wektory AES IV, ponieważ Crypto.CreateEncryptor wymaga tego do odszyfrowania? Czy to oznacza, że użytkownicy muszą przesłać token + IV przy każdym żądaniu?
Mam nadzieję, że to ma sens i dziękuję za odpowiedź z góry.
UPDATE:
Ok, teraz zrobiłem kilka badań i zszedł z tego rozwiązania:
- żeton będzie zawierała pierwotnie określone dane (nazwa użytkownika, data wydania i timeout) Wygenerowano token
- z encrypt-then-mac (zawiera on zaszyfrowane dane AES, wektor IV + znacznik tych 2 wartości do uwierzytelnienia, wygenerowany przy użyciu HMACSHA265)
- znacznik tokena być napisane do db
- użytkownik zostanie uwierzytelniony, jeżeli:
- tag jest ważny (tokenu uwierzytelniania)
- dane można odszyfrować
- żeton nie upłynął jeszcze
- tag odpowiada jeden napisany w bazie
- użytkownik nie jest zablokowany w bazie (na żądanie unieważnienia tokenu)
- klucze będą przechowywane i n oddzielna sekcja web.config. Te same klucze muszą być na każdym serwerze (na zastosowaniu kursu)
nie używałem FormsAuthenticationTicket ponieważ w .NET są następujące kwestie:
- same klucze są używane do różnych celów (MachineKey na widok stanach, zasobów i formauthtickets)
- mac-then-szyfrowania, stosowanych przez .NET nie jest uważany as safe as encrypt-then-mac
- ma wbudowanego w sposób invalidate token before it is expired
Jestem ciekaw, dlaczego przechowujesz dane w tokenie? Jeśli musisz zweryfikować to względem bazy danych, to dlaczego nie przechowywać danych w bazie danych i po prostu użyć Guida lub innego tokenu losowego? –
Z powodu daty wygaśnięcia tokena - chciałem się upewnić, że nie można go zaktualizować w bazie danych + nie musisz robić kwerendy db, jeśli i tak wygasną. –
Powinieneś sprawdzić OAuth (http://oauth.net/), ponieważ jest to w zasadzie to, co opisujesz tutaj. –