Pourquoi utiliser une clé API et un secret?

92

Je suis tombé sur de nombreuses API qui donnent à l'utilisateur à la fois une clé API et un secret . Mais ma question est: quelle est la différence entre les deux?

À mes yeux, une clé peut suffire. Disons que j'ai une clé et que seuls moi et le serveur la connaissons. Je crée un hachage HMAC avec cette clé et fais un appel API. Sur le serveur, nous créons à nouveau le hachage HMAC et le comparons avec le hachage envoyé. Si c'est la même chose, l'appel est authentifié.

Alors pourquoi utiliser deux clés?

Edit: ou cette clé API est-elle utilisée pour rechercher le secret API?

EsTeGe
la source

Réponses:

45

La cryptographie à clé secrète repose sur l'utilisation de la même clé pour encoder puis décoder ultérieurement un message. Ainsi, seuls ceux qui connaissent le "secret" peuvent lire le message.

La sécurité RSA est basée sur 2 clés correspondantes. Il existe une clé publique pour chaque utilisateur, et tout le monde peut (devrait) la connaître. Il existe également une clé privée que seul l'utilisateur doit connaître. Un message chiffré par la clé publique ne peut être déchiffré que par la clé privée, et vice versa.

Ainsi, si je veux vous envoyer un message que vous seul pouvez lire, j'obtiens (du réseau) votre clé publique, je crypte le message avec cette clé et vous êtes la seule personne à pouvoir le décrypter.

Ou, si je veux vous prouver que j'ai envoyé un message, je peux crypter le message avec ma clé privée, vous dire (en texte ouvert ou dans un autre message) comment il a été crypté. Ensuite, vous pouvez déchiffrer le message avec ma clé publique, et s'il devient lisible, vous savez qu'il vient de moi.

Cette forme de cryptage est assez gourmande en informatique, donc ce qui est parfois fait est de crypter une «clé secrète» unique avec la technologie RSA, puis de crypter le reste du message avec la clé secrète, puis de crypter ma signature de la seconde manière. Vous inversez ensuite ce processus afin que si le message et la signature sont lisibles, vous et vous seul pouvez le lire et vous êtes assuré que j'ai envoyé le message.

OU

vous pouvez visiter ce lien pour des explications plus détaillées.

Comment fonctionnent les clés API et les clés secrètes?

SALMAN
la source
9
Bonne réponse, mais lorsque j'utilise des secrets et des clés API avec Facebook ou Gmail, etc., je n'ai à aucun moment à crypter ou hacher quoi que ce soit. Dans ces cas, à quoi servent les secrets et les clés de l'API?
Quintonn du
2
En utilisant Facebook comme exemple, il existe deux scénarios dans lesquels vous utiliseriez app_secret. Le premier ne nécessite pas de hachage. Il est principalement utilisé pour empêcher le piratage de votre URL de redirection. Une fois qu'un utilisateur s'est connecté et a accordé l'accès à votre application si Facebook a envoyé le jeton d'accès directement à l'URL de redirection, vous n'auriez aucun moyen de vérifier si le jeton d'accès provient de Facebook. Je pourrais publier mon propre jeton d'accès sur votre URL de redirection et exécuter des actions Facebook qui proviendraient de votre API. Au lieu de cela, Facebook envoie un code à l'URL de redirection. L'API échange ensuite le code contre le jeton d'accès réel.
Ryan Thomas
2
Au cours de la dernière partie, en échangeant le code contre le jeton d'accès réel, Facebook attend de votre API qu'elle vérifie son identité avec une signature. Dans ce scénario, ils n'ont pas besoin de cryptographie à clé publique pour signer, ils vous font simplement confiance pour garder votre application secrète vraiment secrète et l'utiliser comme signature. Cela m'a toujours semblé idiot de ne pas continuer et d'utiliser une fonction à sens unique pour générer une signature, mais je suppose qu'ils ont là des raisons telles que les performances pour se contenter de l'utilisation directe du secret d'application.
Ryan Thomas
Dans le deuxième cas d'utilisation, vous utilisez le hachage cryptographique. Une fois que vous avez le véritable access_token pour commencer à interagir avec Facebook, vous pouvez souhaiter une sécurité supplémentaire pour empêcher que votre application ne soit usurpée. Dans la console de l'application Facebook, vous pouvez activer une fonctionnalité qui nécessite que chaque demande d'API Facebook de votre application inclue votre signature en plus du jeton d'accès. Je ne fais que deviner leurs motivations, mais je pense qu'à ce stade, ils ne veulent pas que vous envoyiez à plusieurs reprises app_secret comme signature à chaque demande. Plus vous l'envoyez, plus il y a de chances que app_secret soit compromis.
Ryan Thomas
1
Je suppose que depuis que vous avez opté pour cette fonctionnalité de sécurité supplémentaire, vous avez également pris une sorte de décision d'autoriser les performances supplémentaires de Facebook en vérifiant votre signature avec un appel de hachage cryptographique de leur côté. Quoi qu'il en soit, dans ce scénario, vous transmettez deux valeurs avec vos requêtes API Facebook. Access_token et une valeur nommée appsecret_proof qui sert de signature. La preuve de secret d'application est générée par le hachage cryptographique du jeton d'accès en utilisant app_secret comme clé.
Ryan Thomas
55

Vous avez besoin de deux clés distinctes, l'une qui leur indique qui vous êtes et l'autre qui prouve que vous êtes qui vous dites être .

La "clé" est votre identifiant d'utilisateur et le "secret" est votre mot de passe. Ils utilisent simplement les termes «clé» et «secret» parce que c'est ainsi qu'ils l'ont implémenté.

Marcus Adams
la source
1
Et si vous communiquez via https? Quel est l'intérêt de crypter votre message avec une clé secrète alors?
kamuniaft
6
Le but est toujours de réduire les risques. Si la communication https est compromise, un attaquant qui peut lire votre demande ne pourra pas en forger de nouvelles. Si votre API est sur le point de classer des photos de chats, pas de problème, s'il s'agit d'une API de paiement, vous feriez mieux d'avoir plusieurs niveaux de sécurité :)
Yall
Je suppose que le but est deux clés distinctes, c'est parce que différents utilisateurs d'une même application client peuvent avoir des secrets différents, sinon s'ils devaient tous avoir le même secret, avoir une clé n'est pas utile. Droite?
Honey
Pourquoi ces API n'utilisent-elles pas l' Bearer:authentification pour cela? Vous auriez une pièce d'identité et un mot de passe là-bas.
Stefan Haberl
7

Réponse simple, si je l'ai bien compris ...

Si vous utilisez votre clé API pour le chiffrement, comment le service saura-t-il qui les contacte? Comment décrypteront-ils ce message?

Vous utilisez la clé API pour indiquer qui vous êtes, c'est ce que vous envoyez en texte brut. La clé SECRET que vous n'envoyez à personne. Vous l'utilisez simplement pour le cryptage. Ensuite, vous envoyez le message crypté. Vous n'envoyez pas la clé qui a été utilisée pour le chiffrement, cela irait à l'encontre de l'objectif.

ancajic
la source
Tu fais. Vous envoyez la clé API au serveur. Donc, cela signifie que vous donnez cette valeur à toute personne susceptible d'intercepter votre communication avec le serveur.
ancajic
Presque toutes les API que j'ai vues vous ont envoyé à la fois la clé et le secret au serveur. La connexion au serveur est cryptée avec théoriquement le même niveau de sécurité. Mais je ne donne jamais non plus à personne d'autre que le serveur.
sudo
Je n'ai jamais vu l'envoi secreten texte brut. Pouvez-vous me donner un lien? Ce que j'ai vu utilise secretpour crypter certaines données. Et avec les données cryptées, l'envoi apiKeyafin que le serveur sache comment décrypter les données.
ancajic
twilio.com/docs/sms/tutorials / ... et nexmo.github.io/Quickstarts/sms/send sont les exemples que j'ai vus qui m'ont incité à rechercher sur StackOverflow.
sudo
Twilio n'utilise pas exactement ces termes. Mais Nexmo est sûr ... Mais, après un rapide coup d' œil, il semble qu'ils sont simplement appeler les données secretet apiKeyet ce qu'ils font réellement est usernameet password. Ce qui est complètement différent ...
ancajic
3

Il existe des réponses expliquant ce qu'est la clé secrète et (publique). C'est une paire de clés publique-privée à laquelle ils donnent des noms confus. Mais personne ne dit pourquoi les API nécessitent les deux, et de nombreuses API ne vous donnent qu'un seul secret! Je n'ai jamais vu la documentation d'API expliquer pourquoi elles ont deux clés, donc le mieux que je puisse faire est de spéculer ...

Il est préférable de ne mettre que votre clé publique dans votre demande et de signer la demande localement avec votre clé privée; rien de plus ne devrait être nécessaire. Mais certains s'en tirent simplement avec le secret de la demande. Ok, toute bonne API utilisera une sécurité de transport comme TLS (généralement via HTTPS). Mais vous exposez toujours votre clé privée au serveur de cette façon, ce qui augmente le risque qu'ils la gèrent d'une manière ou d'une autre (voir: le bogue de journalisation des mots de passe de GitHub et Twitter récemment découvert). Et HTTPS est théoriquement tout aussi sécurisé, mais il y a toujours des failles de mise en œuvre.

Mais beaucoup - en fait la plupart semble-t-il - les API vous permettent d'envoyer les deux clés dans les requêtes, car c'est plus facile que de faire faire leurs propres signatures; ne peut pas avoir d'exemples cURL purs autrement! Dans ce cas, il est inutile de les séparer. Je suppose que les clés séparées sont juste pour au cas où elles changeraient l'API plus tard pour en profiter. Ou certains ont une bibliothèque cliente qui pourrait le faire de la manière la plus sécurisée.

sudo
la source
0

Une chose que je n'ai pas vue mentionnée ici, bien que ce soit une extension de la réponse de Marcus Adams, est que vous ne devriez pas utiliser une seule information pour identifier et authentifier un utilisateur s'il y a une possibilité d' attaques chronométrées , ce qui peut utilisez les différences de temps de réponse pour deviner jusqu'où une comparaison de chaînes est arrivée.

Si vous utilisez un système qui utilise une «clé» pour rechercher l'utilisateur ou les informations d'identification, cette information peut être devinée progressivement au fil du temps en envoyant des milliers de requêtes et en examinant le temps nécessaire à votre base de données pour trouver (ou non trouver) un enregistrement. Ceci est particulièrement vrai si la "clé" est stockée en texte brut au lieu d'un hachage unidirectionnel de la clé. Vous voudrez stocker les clés des utilisateurs dans un texte brut ou crypté symétriquement si vous avez besoin de pouvoir afficher à nouveau la clé à l'utilisateur.

En ayant une deuxième information, ou "secret", vous pouvez d'abord rechercher l'utilisateur ou les informations d'identification à l'aide de la "clé", qui pourrait être vulnérable à une attaque de synchronisation, puis utiliser une fonction de comparaison sécurisée pour vérifier la valeur de le secret".

Voici l'implémentation de cette fonction par Python:

https://github.com/python/cpython/blob/cd8295ff758891f21084a6a5ad3403d35dda38f7/Modules/_operator.c#L727

Et il est exposé dans la hmaclib (et probablement dans d'autres):

https://docs.python.org/3/library/hmac.html#hmac.compare_digest


Une chose à noter ici est que je ne pense pas que ce type d'attaque fonctionnera sur des valeurs qui sont hachées ou chiffrées avant la recherche, car les valeurs comparées changent de manière aléatoire chaque fois qu'un caractère de la chaîne d'entrée change. J'ai trouvé une bonne explication à cela ici .

Les solutions pour stocker les clés API seraient alors:

  1. Utilisez une clé et un secret séparés, utilisez la clé pour rechercher l'enregistrement et utilisez une comparaison sécurisée pour vérifier le secret. Cela vous permet de montrer à nouveau à l'utilisateur la clé et le secret à un utilisateur.
  2. Utilisez une clé et un secret séparés, utilisez un chiffrement symétrique et déterministe sur le secret et faites une comparaison normale des secrets chiffrés. Cela vous permet de montrer à nouveau à l'utilisateur la clé et le secret, et peut vous éviter d'avoir à implémenter une comparaison sécurisée dans le temps.
  3. Utilisez une clé et un secret séparés, affichez le secret, hachez et stockez-le, puis effectuez une comparaison normale du secret haché. Cela supprime la nécessité d'utiliser un cryptage bidirectionnel et présente l'avantage supplémentaire de garder votre secret sécurisé si le système est compromis. Cela présente l'inconvénient que vous ne pouvez plus montrer le secret à l'utilisateur.
  4. Utilisez une seule clé , montrez-la une fois à l'utilisateur, hachez-la, puis effectuez une recherche normale de la clé hachée ou chiffrée. Cela utilise une seule clé, mais il ne peut pas être montré à nouveau à l'utilisateur. A l'avantage de garder les clés en sécurité si le système est compromis.
  5. Utilisez une seule clé , montrez-la une fois à l'utilisateur, cryptez-la et effectuez une recherche normale du secret crypté. Peut être montré à nouveau à l'utilisateur, mais au prix de la vulnérabilité des clés si le système est compromis.

Parmi ceux-ci, je pense que 3 est le meilleur équilibre entre sécurité et commodité. J'ai vu cela mis en œuvre sur de nombreux sites Web lors de l'émission des clés.

J'invite également tous les experts en sécurité à critiquer cette réponse. Je voulais juste que cela soit un autre point de discussion.

kbuilds
la source