Génération de jetons d’authentification sécurisés par cryptographie

Contexte:

Il s’agit en fait d’une question générale sur les meilleures pratiques, mais certains renseignements sur la situation spécifique pourraient être utiles:

Nous développons une application “connectée” pour l’iPhone. Il communiquera avec l’application backend via les services REST. Afin de ne pas avoir à demander à l’utilisateur un nom d’utilisateur et un mot de passe à chaque lancement de l’application, nous allons exposer un service “Login” qui valide son nom d’utilisateur et son mot de passe lors du lancement initial et renvoie un jeton d’authentification demandes de service pour des données réelles. Le jeton peut avoir une date d’expiration après laquelle nous lui demanderons de se réauthentifier avec son nom d’utilisateur / mot de passe.

La question:

Quelles sont les meilleures pratiques pour générer ce type de jeton à utiliser pour l’authentification?

Par exemple, nous pourrions …

  • Hash (SHA-256, etc) une chaîne aléatoire et stockez-la dans la firebase database pour l’utilisateur donné avec une date d’expiration. Effectuez une recherche simple du jeton lors des demandes suivantes pour vous assurer qu’il correspond.
  • Encryptez l’ID utilisateur et des informations supplémentaires (horodatage, etc.) avec une clé secrète. Déchiffrez le jeton sur les demandes suivantes pour vous assurer qu’il a été émis par nous.

Cela semble être un problème résolu.

Sur la base des commentaires des autres réponses à cette question, des recherches supplémentaires et des discussions hors ligne, voici ce que nous avons fini par faire …

Il a été souligné assez rapidement que le modèle d’interaction ici est essentiellement identique au modèle utilisé par Authentification par formulaire dans ASP.NET lorsqu’une case à cocher “Se souvenir de moi” est activée. Ce n’est simplement pas un navigateur Web qui fait les requêtes HTTP. Notre “ticket” est équivalent au cookie que Forms Authentication définit. L’authentification par formulaires utilise essentiellement une approche de «chiffrement de certaines données avec une clé secrète» par défaut.

Dans notre service Web de connexion, nous utilisons ce code pour créer un ticket:

ssortingng[] userData = new ssortingng[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, ssortingng.Join(UserDataDelimiter, userData) ); // encrypt the ticket ssortingng encryptedTicket = FormsAuthentication.Encrypt(formsTicket); 

Nous avons ensuite un atsortingbut de comportement d’opération pour les services WCF qui ajoute un IParameterInspector qui recherche un ticket valide dans les en-têtes HTTP pour la demande. Les développeurs placent cet atsortingbut de comportement d’opération sur les opérations nécessitant une authentification. Voici comment ce code parsing le ticket:

 // get the Forms Auth ticket object back from the encrypted Ticket FormsAuthenticationTicket formsTicket = FormsAuthentication.Decrypt(encryptedTicket); // split the user data back apart ssortingng[] userData = formsTicket.UserData.Split(new ssortingng[] { UserDataDelimiter }, SsortingngSplitOptions.None); // verify that the username in the ticket matches the username that was sent with the request if (formsTicket.Name == expectedUsername) { // ticket is valid ... } 

Construire votre propre système d’authentification est toujours une “pire pratique”. C’est le genre de chose qu’il vaut mieux laisser aux professionnels spécialisés dans les systèmes d’authentification.

Si vous avez l’intention de créer votre propre architecture de «ticket expirant à partir d’un service de connexion» plutôt que de réutiliser un ticket existant, il est probablement préférable de vous familiariser avec les problèmes qui ont conduit à la conception de systèmes similaires, comme Kerberos. . Une introduction en douceur est ici:

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

Il serait également judicieux d’examiner les failles de sécurité détectées dans Kerberos (et les systèmes similaires) au cours des 20 dernières années et de vous assurer de ne pas les reproduire. Kerberos a été construit par des experts de la sécurité et soigneusement examiné depuis des décennies, et de graves défauts d’algorithmes y sont toujours détectés, comme celui-ci:

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

Il est préférable d’apprendre de leurs erreurs que les vôtres.

Amazon.com utilise un jeton de message HMAC SHA-1 pour authentifier et autoriser les demandes. Ils l’utilisent pour un service commercial assez important, je serais donc susceptible de faire confiance à leurs décisions d’ingénierie. Google publie l’ API OpenSocial qui est un peu similaire. Basé sur Google et Amazon.com utilisant des approches similaires et publiées pour sécuriser les requêtes Web, je pense que ce sont probablement de bonnes façons de faire.

Chacune des deux réponses que vous avez fournies suffira. Vous pouvez trouver des frameworks là-bas qui font cela pour vous, mais la vérité est que ce n’est pas si difficile à construire. Le choix des jetons stockés dans la firebase database par rapport aux données cryptées est une décision architecturale – voulez-vous effectuer une recherche dans la firebase database à chaque vue de la page ou préférez-vous mastiquer le processeur avec le déchiffrement des cookies? Dans la plupart des applications, l’utilisation de cookies cryptés permet de gagner en performance à grande échelle (si cela pose un problème). Sinon c’est juste une question de goût.

Puisque vous utilisez WCF, vous disposez de plusieurs options si vous utilisez CFNetwork, par exemple NTLM ou Digest Authentication:

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

Je sais que cela ne répond pas à votre question spécifique, mais j’ai également été confronté à ce problème (iPhone – Tomcat) et j’ai décidé d’utiliser les services d’authentification sur le serveur Web autant que possible. Il n’y a pas de pénalité significative pour inclure les informations d’authentification à chaque demande dans la plupart des cas. Un rapide Google met en ligne de nombreux articles sur les services WCF et RESTful (et des questions connexes sur StackOverflow).

J’espère que cela t’aides!

Vous devez implémenter:

  1. OAuth2 Implicit Grant – pour les applications tierces http://tools.ietf.org/html/rfc6749#section-1.3.2
  2. Informations d’identification OAuth2 Resource Owner – pour votre propre application mobile http://tools.ietf.org/html/rfc6749#section-1.3.3

qui sont exactement les workflows de OAuth2 que vous recherchez. Ne réinventez pas la roue.

Cela ressemble simplement à un identifiant de session avec un long délai d’expiration. Les mêmes principes utilisés dans les applications Web pourraient s’appliquer ici.

Plutôt que de coder des informations, les identifiants de session sont choisis aléatoirement dans un très grand espace (128 bits). Le serveur conserve un enregistrement associant l’identifiant de session à l’utilisateur et d’autres informations souhaitées telles que le délai d’expiration. Le client présente l’identifiant de session sur un canal sécurisé avec chaque requête.

La sécurité repose sur l’imprévisibilité des identifiants de session. Générez-les avec un RNG cryptographique, à partir d’un très grand espace.