Sprawdzone metody generowania tokenów OAuth?


100

Zdaję sobie sprawę, że specyfikacja OAuth nie określa nic o pochodzeniu kodu ConsumerKey, ConsumerSecret, AccessToken, RequestToken, TokenSecret lub Verifier, ale jestem ciekawy, czy istnieją jakieś najlepsze praktyki dotyczące tworzenia znacząco bezpiecznych tokenów (zwłaszcza Token / Tajne kombinacje).

Jak widzę, istnieje kilka podejść do tworzenia tokenów:

  1. Po prostu użyj losowych bajtów, przechowuj w bazie danych powiązanej z konsumentem / użytkownikiem
  2. Hashuj niektóre dane specyficzne dla użytkownika / konsumenta, przechowuj w bazie danych powiązanej z konsumentem / użytkownikiem
  3. Szyfruj dane specyficzne dla użytkownika / konsumenta

Zaletą (1) jest to, że baza danych jest jedynym źródłem informacji, które wydaje się najbezpieczniejsze. Trudniej byłoby przeprowadzić atak przeciwko (2) lub (3).

Haszowanie rzeczywistych danych (2) pozwoliłoby na ponowne wygenerowanie tokena z przypuszczalnie już znanych danych. Może naprawdę nie zapewniać żadnych korzyści dla (1), ponieważ i tak musiałby przechowywać / wyszukiwać. Bardziej obciążający procesor niż (1).

Szyfrowanie prawdziwych danych (3) pozwoliłoby na odszyfrowanie informacji. Wymagałoby to mniej miejsca i potencjalnie mniej wyszukiwań niż (1) i (2), ale także potencjalnie mniej bezpieczne.

Czy są jakieś inne podejścia / zalety / wady, które należy wziąć pod uwagę?

EDYCJA: inną kwestią jest to, że MUSI istnieć jakaś losowa wartość w tokenach, ponieważ musi istnieć możliwość wygaśnięcia i ponownego wydania nowych tokenów, więc nie mogą one składać się tylko z prawdziwych danych.

Śledź pytania :

Czy istnieje minimalna długość tokenu, aby zapewnić znaczne bezpieczeństwo kryptograficzne? Jak rozumiem, dłuższe Token Secrets stworzyłyby bezpieczniejsze podpisy. Czy to rozumienie jest prawidłowe?

Czy są zalety używania określonego kodowania w porównaniu z innym z perspektywy mieszania? Na przykład widzę wiele API używających kodowania szesnastkowego (np. Ciągi GUID). W algorytmie podpisywania OAuth token jest używany jako ciąg. W przypadku łańcucha szesnastkowego dostępny zestaw znaków byłby znacznie mniejszy (bardziej przewidywalny) niż powiedzmy z kodowaniem Base64. Wydaje mi się, że dla dwóch ciągów o jednakowej długości, ten z większym zestawem znaków miałby lepszą / szerszą dystrybucję hashów. Wydaje mi się, że poprawiłoby to bezpieczeństwo. Czy to założenie jest słuszne?

Specyfikacja OAuth porusza ten problem w 11.10 Entropy of Secrets .


Dlaczego szyfrowanie? Czy haszowanie nie jest wystarczająco dobre? Jeśli samo haszowanie jest wystarczające dla hasła, czy nie powinno być jeszcze lepiej w przypadku dłuższych tokenów dostępu?
AlikElzin-kilaka

Minęło 7,5 roku, odkąd zadałem to pytanie. Naprawdę nie pamiętam.
mckamey

1
Czytanie ponownie, haszowanie i szyfrowanie były sugerowanymi dwoma różnymi podejściami. Szyfrowanie pozwoliłoby serwerowi uzyskać pewne informacje bez wyszukiwania bazy danych. To był jeden z wielu kompromisów.
mckamey

Odpowiedzi:


93

OAuth nie mówi nic o tokenie poza tym, że jest z nim powiązany sekret. Więc wszystkie wspomniane schematy będą działać. Nasz token ewoluował wraz z powiększaniem się witryn. Oto wersje, których używaliśmy wcześniej,

  1. Nasz pierwszy token to zaszyfrowany BLOB z nazwą użytkownika, sekretem tokena i terminem ważności itp. Problem polega na tym, że nie możemy unieważnić tokenów bez żadnego rekordu na hoście.

  2. Zmieniliśmy więc to, aby wszystko było w bazie danych, a token jest po prostu losową liczbą używaną jako klucz do bazy danych. Ma indeks nazwy użytkownika, więc łatwo jest wyświetlić listę wszystkich tokenów dla użytkownika i odwołać go.

  3. Dostajemy sporo działań hakerskich. W przypadku liczby losowej musimy udać się do bazy danych, aby sprawdzić, czy token jest ważny. Więc wróciliśmy do zaszyfrowanego BLOBa ponownie. Tym razem token zawiera tylko zaszyfrowaną wartość klucza i datę ważności. Dzięki temu możemy wykryć nieprawidłowe lub wygasłe tokeny bez wchodzenia do bazy danych.

Niektóre szczegóły implementacji, które mogą Ci pomóc,

  1. Dodaj wersję do tokena, abyś mógł zmienić format tokena bez niszczenia istniejących. Cały nasz token ma pierwszy bajt jako wersję.
  2. Użyj wersji Base64 bezpiecznej dla adresów URL, aby zakodować BLOB, aby nie musieć zajmować się problemami z kodowaniem adresów URL, co utrudnia debugowanie z podpisem OAuth, ponieważ możesz zobaczyć potrójnie zakodowany łańcuch bazowy.

2
Wspaniale, dziękuje. Pomysł na wersję jest dobry. Uruchomiłem przyjazny dla adresów URL Base64, ale żałuję, że nie mam kodowania ściśle alfanumerycznego, aby jeszcze łatwiej było czytać.
mckamey

Nie pomyślałem o tym wcześniej, bardzo interesujące! Planowałem buforowanie kluczy APC, aby nie obciążać bazy danych przez cały dzień, zanim to przeczytam. Nadal nie jestem pewien, czy może to nie być dużo wolniejsze niż wyszukiwanie w pamięci współdzielonej, które robi APC (przynajmniej przy drugim, trzecim itd. Żądaniu w rozsądnym czasie).
Philzen
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.