Generowanie kryptograficznie bezpiecznych tokenów uwierzytelniania

Background:

To jest naprawdę ogólne Pytanie o najlepsze praktyki, ale pewne tło dotyczące konkretnej sytuacji może być pomocne:

Tworzymy aplikację "connected" dla iPhone ' a. Będzie komunikować się z aplikacją backend za pośrednictwem usług REST. Aby nie musieć prosić użytkownika o nazwę użytkownika i hasło za każdym razem, gdy uruchamia aplikację, wystawimy usługę "Login", która sprawdza jego nazwę użytkownika i hasło na początku uruchamia i zwraca token uwierzytelniania, który może być używany do przyszłych żądań usług internetowych dla prawdziwych danych. Token może mieć czas wygaśnięcia, po którym poprosimy go o ponowne uwierzytelnienie przy użyciu nazwy użytkownika/hasła.

Pytanie:

Jakie są najlepsze praktyki generowania tego rodzaju tokenów, które mają być używane do uwierzytelniania?

Na przykład, możemy...

  • Hash (SHA-256, etc) losowy ciąg znaków i przechowuje go w bazie danych dla podanego użytkownika wraz z datą ważności. Wykonaj proste wyszukiwanie tokenu przy kolejnych żądaniach, aby upewnić się, że jest zgodny.
  • Zaszyfruj identyfikator użytkownika i dodatkowe informacje (znacznik czasu itp.) tajnym kluczem. Odszyfruj token przy kolejnych żądaniach, aby upewnić się, że został wydany przez nas.

Wydaje mi się, że to musi być rozwiązany problem.

Author: Erv Walter, 2009-05-08

7 answers

Na podstawie opinii innych odpowiedzi na to pytanie, dodatkowych badań i dyskusji offline, oto, co zrobiliśmy...

Dość szybko zauważono, że model interakcji tutaj jest zasadniczo dokładnie taki sam jak model używany przez uwierzytelnianie formularzy w ASP.NET Gdy zaznaczone jest pole wyboru "Zapamiętaj mnie". To po prostu nie jest przeglądarka internetowa dokonująca żądań HTTP. Nasz "bilet" jest równy plikowi cookie, który tworzy zestawy uwierzytelniania. Formularze Uwierzytelnianie wykorzystuje domyślnie metodę "szyfrowania niektórych danych za pomocą tajnego klucza".

W naszej usłudze logowania używamy tego kodu do tworzenia paragonu:

string[] userData = new string[4];

// fill the userData array with the information we need for subsequent requests
userData[0] = ...; // data we need
userData[1] = ...; // other data, etc

// create a Forms Auth ticket with the username and the user data. 
FormsAuthenticationTicket formsTicket = new FormsAuthenticationTicket(
    1,
    username,
    DateTime.Now,
    DateTime.Now.AddMinutes(DefaultTimeout),
    true,
    string.Join(UserDataDelimiter, userData)
    );

// encrypt the ticket
string encryptedTicket = FormsAuthentication.Encrypt(formsTicket);

Następnie mamy atrybut zachowania operacji dla usług WCF, który dodaje IParameterInspector, który sprawdza poprawny bilet w nagłówkach HTTP dla żądania. Programiści przypisują ten atrybut zachowania operacji operacjom wymagającym uwierzytelnienia. Oto jak ten kod parsuje bilet:

// get the Forms Auth ticket object back from the encrypted Ticket
FormsAuthenticationTicket formsTicket = FormsAuthentication.Decrypt(encryptedTicket);

// split the user data back apart
string[] userData = formsTicket.UserData.Split(new string[] { UserDataDelimiter }, StringSplitOptions.None);

// verify that the username in the ticket matches the username that was sent with the request
if (formsTicket.Name == expectedUsername)
{
    // ticket is valid
    ...
}
 29
Author: Erv Walter,
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
2009-05-13 15:44:24

Budowanie własnego systemu uwierzytelniania jest zawsze "najgorszą praktyką". To najlepiej pozostawić profesjonalistom specjalizującym się w systemach uwierzytelniania.

Jeśli zależy ci na zbudowaniu własnej architektury "wygasającego biletu z usługi logowania", a nie na ponownym wykorzystaniu istniejącej, prawdopodobnie dobrym pomysłem jest przynajmniej zapoznanie się z problemami, które napędzały projektowanie podobnych systemów, takich jak Kerberos. Łagodnym wstępem jest tutaj:

Http://web.mit.edu/kerberos/dialogue.html

Dobrym pomysłem byłoby również sprawdzenie, jakie dziury w zabezpieczeniach zostały znalezione w Kerberos (i podobnych systemach) w ciągu ostatnich 20 lat i upewnienie się, że ich nie powielasz. Kerberos został zbudowany przez ekspertów ds. bezpieczeństwa i starannie sprawdzany przez dziesięciolecia, a nadal znajdują się w nim poważne wady algorytmiczne, takie jak jeden:

Http://web.mit.edu/kerberos/www/advisories/MITKRB5-SA-2003-004-krb4.txt

O wiele lepiej uczyć się na ich błędach niż na własnych.

 11
Author: Eric Lippert,
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
2009-05-08 17:46:40

Amazon.com używa tokena wiadomości HMAC SHA-1 do uwierzytelniania i autoryzacji żądań. Używają tego do dość dużych usług komercyjnych, więc będę musiał zaufać ich decyzjom inżynieryjnym. Google publikuje OpenSocial API, który jest nieco podobny. Na podstawie Google i Amazon.com korzystając z podobnych i otwarcie opublikowanych podejść do zabezpieczania żądań internetowych, podejrzewam, że są to prawdopodobnie dobre sposoby.

 10
Author: Alex Reynolds,
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
2009-05-08 20:04:15

Jedna z dwóch odpowiedzi, które podałeś, wystarczy. Możesz znaleźć ramy, które robią to za ciebie, ale prawda jest taka, że nie jest to trudne do zbudowania. (Każda firma, dla której pracowałem ma swoje własne.) Wybór tokenów przechowywanych w bazie danych w porównaniu z zaszyfrowanymi "ciasteczkami" danych jest decyzją architektoniczną - chcesz przeszukiwać bazę danych w każdym widoku strony, czy wolisz przegryzać PROCESOR za pomocą odszyfrowywania ciasteczek? W większości aplikacji używanie zaszyfrowanych plików cookie zapewnia wydajność wygrać w skali (jeśli to problem). Inaczej to tylko kwestia gustu.

 3
Author: Neil Mix,
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
2009-05-13 02:24:50

Ponieważ używasz WCF, masz wiele opcji, jeśli używasz CFNetwork -- na przykład NTLM lub Digest Authentication:

Http://developer.apple.com/documentation/Networking/Conceptual/CFNetwork/Concepts/Concepts.html#//apple_ref/doc/uid/TP30001132-CH4-SW7

Wiem, że to nie odpowiada na twoje konkretne pytanie, ale miałem również do czynienia z tym problemem (iPhone-Tomcat ) i zdecydowałem się korzystać z usług uwierzytelniania na serwerze WWW w jak największym stopniu. W większości przypadków nie ma znaczącej kary za dołączenie informacji uwierzytelniających do każdego żądania. Szybkie Google wyświetla wiele postów na blogu na temat WCF i usług RESTful (i kilka powiązanych pytań na temat StackOverflow).

Mam nadzieję, że to pomoże!

 1
Author: sehugg,
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
2009-05-10 02:19:00

Powinieneś zaimplementować:

  1. OAuth2 Implicit Grant-for third-party applications http://tools.ietf.org/html/rfc6749#section-1.3.2
  2. OAuth2 resource Owner password Credentials - for your own mobile application http://tools.ietf.org/html/rfc6749#section-1.3.3

Które są dokładnie tymi przepływami pracy, od OAuth2, których szukasz. Nie odkrywaj koła na nowo.

 1
Author: irakli,
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
2014-07-27 20:03:53

To po prostu brzmi jak identyfikator sesji z długim czasem wygaśnięcia. Te same zasady stosowane do tego w aplikacjach internetowych mogą mieć zastosowanie tutaj.

Zamiast kodowania informacji, identyfikatory sesji są wybierane losowo z bardzo dużej przestrzeni (128 bitów). Serwer prowadzi rejestr kojarzenia identyfikatora sesji z użytkownikiem i innych żądanych informacji, takich jak czas wygaśnięcia. Klient przedstawia identyfikator sesji Przez bezpieczny kanał z każdym Prośba.

Bezpieczeństwo zależy od nieprzewidywalności identyfikatorów sesji. Wygeneruj je za pomocą kryptograficznego RNG, z bardzo dużej przestrzeni.

 0
Author: erickson,
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
2009-05-08 16:09:44