56 votes

Génération de jetons d'authentification sécurisés de manière cryptographique

Arrière-plan:

C'est vraiment les meilleures pratiques de la question, mais quelques informations sur la situation spécifique pourrait être utile:

Nous développons une "connecté" de l'application pour l'iPhone. Il communique avec l'application backend via des services REST. Afin de ne pas avoir à inviter l'utilisateur à entrer un nom d'utilisateur et mot de passe à chaque lancement de l'application, nous allons exposer un "Login" de service qui valide leur nom d'utilisateur et mot de passe sur le lancement initial et renvoie un jeton d'authentification qui peut être utilisé pour de futures demandes de service web pour les données réelles. Le jeton peut avoir un délai d'expiration après laquelle nous allons leur demander de se ré-authentifier avec leur nom d'utilisateur/mot de passe.

La Question:

Quelles sont les meilleures pratiques pour la génération de ce type de jeton à utiliser pour l'authentification?

Par exemple, nous pourrions...

  • Table de hachage (SHA-256, etc) une chaîne de caractères aléatoires et de le stocker dans la base de données pour l'utilisateur avec une date d'expiration. Faire une recherche simple de l'jeton sur les requêtes suivantes pour vous assurer qu'il correspond.
  • Encrypte l'id de l'utilisateur et des informations supplémentaires (timestamp, etc) avec une clé secrète. Décrypter le pion à des demandes ultérieures assurez-vous qu'il a été émis par nous.

Cela se sent comme il doit être un problème résolu.

29voto

Erv Walter Points 6756

Basé sur les commentaires des autres réponses à cette question, d'autres recherches, et des discussions hors-ligne, voici ce que nous avons fini par le faire...

Il a été souligné assez rapidement que le modèle d'interaction est ici essentiellement exactement le même que le modèle utilisé par l'Authentification de Formulaires en ASP.NET quand un "remember me" est cochée. Ce n'est pas un navigateur web rendant les requêtes HTTP. Notre "billet" est équivalent à le cookie d'Authentification de Formulaires, jeux de. Les formulaires d'Authentification utilise essentiellement un "chiffrer des données avec une clé secrète" approche par défaut.

Dans notre web d'ouverture de service, nous utiliser ce code pour créer un ticket:

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);

Ensuite, nous avons une opération comportement de l'attribut pour les services WCF qui ajoute un IParameterInspector qui vérifie la validité du billet dans les en-têtes HTTP de la requête. Développeurs de mettre cette opération comportement de l'attribut sur les opérations qui nécessitent une authentification. Voici comment ce code traite le billet:

// 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
    ...
}

13voto

Eric Lippert Points 300275

La construction de votre propre système d'authentification est toujours un "le pire de la pratique". C'est le genre de chose mieux laisser aux professionnels qui se spécialisent dans les systèmes d'authentification.

Si vous êtes plié sur la construction de votre propre "qui expire le billet d'un service de connexion à" l'architecture plutôt que de recréer à partir d'un existant, c'est probablement une bonne idée au moins familiariser avec les questions qui ont motivé la conception de systèmes similaires, comme Kerberos. Une introduction en douceur est ici:

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

Il serait également une bonne idée de prendre un coup d'oeil à ce que les trous de sécurité ont été trouvées dans Kerberos (et des systèmes similaires) au cours des 20 dernières années, et assurez-vous de ne pas les reproduire. Kerberos a été construit par les experts en sécurité et examiné avec soin depuis des décennies, et encore de graves algorithmique défauts sont d'être trouvé en lui, comme celui-ci:

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

C'est beaucoup mieux d'apprendre de leurs erreurs.

11voto

Alex Reynolds Points 45039

Amazon.com utilise un algorithme HMAC SHA-1 message jeton pour authentifier et autoriser les demandes. Ils utilisent cela pour un assez grand service commercial, je serais responsable de faire confiance à leurs décisions d'ingénierie. Google publie le OpenSocial de l'API qui est un peu similaire. Basé sur Google et Amazon.com en utilisant les mêmes et ouvertement publié approches de sécurisation web demandes, je soupçonne que ce sont probablement les bonnes façons de le faire.

3voto

Neil Mix Points 811

L'une des deux réponses que vous avez fournies suffira. Vous pouvez trouver des cadres qui n'ont pour vous, mais la vérité est qu'il n'est pas difficile à construire. (Chaque compagnie, j'ai travaillé a rouler leur propre.) Le choix de la base de données stockée jetons rapport à des données chiffrées des "cookies" est une décision architecturale -- voulez-vous engager une base de données de recherche sur chaque page vue, ou préférez-vous vous chew CPU avec témoin de déchiffrement? Dans la plupart des applications, à l'aide chiffrée des cookies fournit une performance de gagner à l'échelle (si c'est un sujet de préoccupation). Sinon, c'est juste une question de goût.

1voto

sehugg Points 1862

Puisque vous êtes en utilisant WCF, vous avez une variété d'options si vous utilisez CFNetwork -- par exemple ou NTLM pour l'Authentification Digest:

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

Je sais que ce n'est pas la réponse à votre question, mais j'ai aussi été confronté à ce problème (iPhone - Tomcat) et a décidé d'utiliser les services d'authentification sur le serveur web autant que possible. Il n'y a pas de pénalité importante, y compris pour les informations d'authentification à chaque demande dans la plupart des cas. Un rapide Google tourne beaucoup de messages de blog sur WCF de repos et de services (et des questions connexes sur StackOverflow).

Espérons que cette aide!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X