web-dev-qa-db-fra.com

Comment stocker en toute sécurité les jetons porteurs sur le serveur?

Imaginez que vous utilisez un service qui met en œuvre un OAuth 2.0 flux pour permettre à vos utilisateurs finaux de se connecter à des applications 3ème partie, et d'autoriser les applications à consommer grâce à une API de données de votre service.
Lors de l'authentification avec succès une application 3ème partie par votre OAuth flux, votre service envoie l'application 3ème partie porteur jeton qui authentifie (et autorise) l'application 3ème partie (au nom de l'utilisateur final) à utiliser l'API de votre service.

Un tel adhésif doit être stocké sur vos serveurs afin d'effectuer une authentification pour les appels d'API entrants. Étant donné que le jeton porteur authentifie (et autorise) les clients, vous devez le stocker en toute sécurité, comme si vous stockiez un mot de passe.
[.

En cas de jeton au porteur, il n'ya pas de capital à utiliser pour rechercher des références/jetons correspondant. En supposant que vous souhaitiez stocker des jetons porteurs tels que des mots de passe (salé + hachés), vous devez rechercher tous les sels possibles, appliquez chacun, puis de hachage le jeton salé, puis vérifiez s'il existe n'importe où dans votre système. Ça ne fait pas échoue.

Donc, ma question est la suivante : Comment pouvez-vous stocker en toute sécurité les jetons porteurs sur votre serveur? C'est-à-dire sans avoir à générer toutes les représentations sécurisées possibles à chaque fois que vous devez vérifier un jeton.
[.____] par "Tokens au porteur en toute sécurité", je veux dire qu'un attaquant qui obtient le fichier de tous les jetons porteurs "stockés en toute sécurité" ne pourra pas les utiliser.

6
derabbink

Si les demandes de la tierce partie au OAuth fournisseur disposent d'autres données associant la demande à l'utilisateur, par exemple le nom ou ID de l'utilisateur, le serveur pourrait stocker le jeton porteur comme un mot de passe régulier. avec des sels individuels. Toutefois, si les demandes tiers ne disposent pas d'informations identifiables, le serveur pourrait stocker une version sautée + hachée du jeton au porteur avec un sel partagé pour tous les jetons porteurs. Parce OAuth Les jetons expirent rapidement un sel unique n'est pas aussi important que celui d'un mot de passe qui pourrait ne jamais expirer. Si le jeton expire après 6-12 heures, l'attaquant ne peut pas craquer de manière réaliste le hachage et l'utiliser pour accéder à un utilisateur compte. Le serveur pourrait ensuite faire pivoter périodiquement le sel chaque semaine environ pour une sécurité supplémentaire.

2
Justin Moore

Basé sur Réponse de Justin , je construisais le mien.

Si les jetons sont assez longs (dans mon cas, ils sont 200 alphanumériques ([A-Za-z0-9]) Les personnages, il n'est pas nécessaire de les saler. Le hachage seul devrait alors suffire, car la complexité est suffisamment élevée.

Si les jetons ne sont pas assez longs pour vous éloigner de hachage uniquement (ou si vous souhaitez insister pour les saluer également), vous pouvez modifier légèrement le schéma de génération de jeton: au lieu de générer un jeton aléatoire, générez également un directeur spécifique de jeton. Ensuite, concatéez les deux et remettez le résultat à l'application de consommation comme un seul jeton. Cela demande essentiellement aux clients de l'API d'envoyer également des informations d'identification de l'utilisateur, mais elle est commodément intégrée à un seul jeton.

En interne, vous sel + hachage le jeton réel avant de stocker et stocker le directeur spécifique du jeton séparément. En ce qui concerne la vérification d'un jeton, vous divisez le jeton soumis en deux, récupérer le jeton réel et le principal du jeton. Ce directeur peut ensuite être utilisé pour rechercher le jeton réel salé + haché sur lequel vous pouvez exécuter un matcheur.

Exemple de béton:

  1. Générez un jeton porteur: par exemple. a0z9B1Y8c2x7
  2. Générez une principale principale de jeton fixe: par exemple D3W6e4v5F5
  3. Générer un sel, par exemple aabbccddeeff00112233445566778899
  4. Sel + hachage le jeton au porteur (a0z9B1Y8c2x7), qui entraînerait quelque chose comme ceci: xyzXYZabcABC
  5. rangez le jeton salé + haché aux côtés du principal du capital de la jeton, c'est-à-dire Stocker un tuple (xyzXYZabcABC, D3W6e4v5F5)
  6. Donnez la concaténation du jeton et du directeur de l'utilisateur, de traiter comme jeton au porteur régulier: a0z9B1Y8c2x7D3W6e4v5F5
1
derabbink