Je construisais un service Web RESTful lorsque je suis tombé sur des jetons Web JSON comme alternative aux cookies traditionnels pour l'authentification. Le cœur conceptuel de cette méthode est que le serveur est le seul agent qui connaît la clé secrète utilisée pour digérer (généralement en utilisant HS256) la charge utile, de sorte que lui seul peut déterminer si le client a modifié le contenu du message. Ma préoccupation avec cette approche est la suivante: comment puis-je stocker en toute sécurité la clé secrète utilisée par le serveur pour chiffrer la charge utile? Dois-je le changer périodiquement? Dois-je le générer "au hasard"?
J'ai pensé à générer une chaîne "aléatoire" lorsque mon service Web RESTful est initialisé et à le stocker dans une "variable globale" utilisée ensuite pour digérer mes charges utiles. Cependant, je crains la possibilité qu'un autre processus accède à mon REST api 'espace mémoire' ou que mon système d'exploitation fonctionnalité de mémoire virtuelle expose ma clé secrète.
La réalité est que si d'autres processus peuvent accéder à votre mémoire de processus ou aux fonctionnalités de votre machine virtuelle, le jeu est probablement terminé car vous êtes déjà compromis. Si un processus a accès à ce niveau, il peut probablement obtenir d'autres informations, telles que les informations d'identification initiales utilisées pour s'authentifier avant d'obtenir le jeton ou simplement modifier les résultats pour que la vérification du jeton soit vraie malgré le résultat de la vérification, etc. Ne vous concentrez pas trop beaucoup sur les possibilités extrêmes. La plupart des compromis se produisent par des exploits beaucoup plus simples ou des erreurs de configuration, comme le stockage de la clé privée sur le système de fichiers qui est lisible dans le monde entier et accessible à votre serveur Web, etc.
La meilleure façon de gérer les clés et les secrets dépendra un peu de votre plateforme. Certaines plates-formes fournissent des cadres de gestion clés et peut-être utiliser l'un d'eux serait approprié.
Ne vous concentrez pas trop sur le fait qu'il s'agit d'une clé secrète. En réalité, il n'est pas plus critique que les autres informations d'identification que vous devez gérer. Par exemple, comment gérez-vous les informations d'identification qui permettent d'accéder à vos bases de données? Si cette solution est suffisamment bonne pour vos bases de données, elle est probablement suffisante pour votre clé secrète. Si ce n'est pas le cas, je vous demanderais s'il est réellement assez bon pour votre base de données. La réalité est que si quelqu'un va compromettre le système, il est probable qu'il le fasse pour avoir accès aux données/services fournis par l'interface. Dans la plupart des cas, ce service ou cette base de données sous-jacente a également besoin d'informations d'identification et de gestion des informations d'identification et ce sont les vraies clés du royaume.
Je pense qu'il est préférable d'utiliser une approche cohérente pour gérer toutes les informations d'identification dont votre application a besoin et de ne pas traiter la clé secrète pour la création/vérification de jetons comme très spéciale. Ne pensez pas trop à la solution simplement parce qu'elle implique des mots comme "clé" ou "secret". Toutes les informations d'identification sont des données sensibles qui doivent être gérées de manière sécurisée. Une grande partie des erreurs commises sont dues à des solutions complexes sur-conçues qui deviennent difficiles à maintenir et faciles à se tromper. Envisagez des solutions qui utilisent des installations/cadres existants, connus et testés, tels que keytool, gestionnaires de porte-clés, etc. À défaut, utilisez quelque chose qui peut être facilement compris et maintenu. Quelque chose d'aussi simple qu'une base de données peut suffire. Évitez les solutions qui impliquent de stocker les informations sous forme de constantes ou de variables globales, car cela peut devenir difficile à maintenir, car changer la clé signifie maintenant un changement de code et vous devez maintenant tester, gérer le changement et promouvoir la production, etc.
Quant à la façon dont vous générez les clés, cela dépendra de votre environnement et des types/niveaux de risques que vous devez gérer. En règle générale, je me méfie toujours de tout ce qui repose sur le "hasard". La génération de vraies valeurs aléatoires est extrêmement difficile et ne fait souvent rien pour améliorer la sécurité. En fait, les hypothèses de hasard qui se sont avérées par la suite non aléatoires peuvent révéler des modèles, ce qui signifie à son tour la possibilité de prédire les valeurs futures, ce qui est presque toujours une mauvaise chose lorsque vous parlez de clés. Dans ce scénario, je ne pense pas que l'aléatoire va vous gagner beaucoup du point de vue de la sécurité, sauf si vous êtes dans un environnement où il est essentiel que les administrateurs système ne connaissent pas la clé. De même, un changement régulier de la clé est peu susceptible de fournir autre chose que des inconvénients pour vos utilisateurs. Chaque fois que vous modifiez la clé, tous les jetons actuellement émis deviennent invalides. Vous voudrez peut-être envisager d'avoir une politique pour changer la clé lorsque le personnel quitte ou changer de rôle et vous pouvez même envisager une politique pour changer la clé chaque fois que le logiciel est mis à jour, etc.
Cependant, il est peu probable que le changement religieux de clé chaque semaine apporte quelque chose en matière de sécurité.
Notez que ce qui précède n'est pas vrai pour toutes les clés. Il existe des situations où une clé privée doit être gérée avec une extrême prudence - par exemple, la clé privée pour l'autorité de certification racine. Toutes les clés ne sont pas égales. Votre approche de gestion doit correspondre aux exigences et aux risques contre lesquels vous devez vous protéger. Dans le cas de JWT, vous avez affaire à un écosystème largement fermé - la clé est utilisée pour générer/signer et vérifier les jetons. L'objectif est de détecter la falsification et non la protection du secret. Le risque est que si quelqu'un obtient la clé, il peut créer des jetons falsifiés et obtenir un accès non autorisé à votre service. Ce que cela signifie en fin de compte dépend du service. La mesure dans laquelle quelqu'un tentera de le faire dépend également du service sous-jacent et de sa valeur perçue. Les longueurs auxquelles vous vous livrez pour sécuriser la clé doivent refléter la menace.