Comment puis-je m'assurer que mon API REST ne répond qu'aux demandes générées par des clients approuvés, dans mon cas, mes propres applications mobiles? Je veux empêcher les demandes indésirables provenant d'autres sources. Je ne veux pas que les utilisateurs remplissent une clé de série ou quoi que ce soit, cela devrait se faire en coulisse, lors de l'installation et sans aucune interaction de l'utilisateur.
Autant que je sache, HTTPS ne sert qu'à valider le serveur avec lequel vous communiquez, c'est à qui il est destiné. Je vais bien sûr utiliser HTTPS pour chiffrer les données.
Y a-t-il un moyen d'accomplir cela?
Mise à jour: l'utilisateur peut effectuer des actions en lecture seule, ne nécessitant pas d'être connecté, mais également des actions en écriture, qui nécessitent que l'utilisateur soit connecté (authentification par jeton d'accès). Dans les deux cas, je souhaite que l'API réponde aux demandes provenant d'applications mobiles sécurisées.
L'API sera également utilisé pour l'enregistrement d'un nouveau compte via l'application mobile.
Mise à jour 2: Il semble y avoir plusieurs réponses à cette question, mais honnêtement, je ne sais pas laquelle indiquer. Certains disent que cela peut être fait, d'autres pas.
Réponses:
Vous ne pouvez pas.
Vous ne pouvez jamais vérifier une entité, aucune entité , que ce soit une personne, un client matériel ou un client logiciel. Vous pouvez seulement vérifier que ce qu'ils vous disent est correct, puis présumez l’honnêteté .
Par exemple, comment Google sait-il que je me connecte à mon compte Gmail? Ils me demandent simplement un nom d'utilisateur et un mot de passe, vérifient cela , puis supposent l'honnêteté, car qui d'autre aurait cette information? À un certain moment Google a décidé que cela ne suffisait pas et a ajouté la vérification du comportement ( à la recherche d' un comportement étrange) , mais qui est toujours sur la fonde personne pour faire le comportement , puis validez le comportement .
C'est exactement la même chose avec la validation du client. Vous pouvez uniquement valider le comportement du client, mais pas le client lui-même.
Donc, avec SSL, vous pouvez vérifier que le client possède un certificat valide ou non. Vous pouvez donc simplement installer votre application, obtenir le certificat, puis exécuter tout nouveau code.
La question est donc: pourquoi est-ce si critique? Si cela pose un réel problème, je m'interrogerais sur votre choix d'un gros client. Peut-être devriez-vous utiliser une application Web (pour ne pas avoir à exposer votre API).
Voir aussi: Suppression de la validation de certificat SSL pour les applications Android
et: Quel est le degré de sécurité des certificats SSL clients dans une application mobile?
la source
Je suis sûr que vous êtes à l'aise avec les connexions des utilisateurs et les communications via SSL. Je vais donc me concentrer sur la partie la plus intéressante de la question: comment faire en sorte que vos actions en lecture seule - qui n'exigent pas que l' utilisateur soit authentifié - ne sont acceptés que depuis vos propres applications clientes?
Avant toute chose, il y a l'inconvénient auquel fNek a fait allusion dans une réponse précédente: vos applications clientes sont entre les mains d'utilisateurs potentiellement hostiles. Ils peuvent être examinés, leurs communications inspectées, leur code désassemblé. Rien de ce que je vais suggérer ne vous permettra de garantir que quelqu'un ne procédera pas à l'ingénierie inverse de votre client et n'abuse pas de votre API REST. Mais il devrait mettre une barrière devant toute tentative fortuite.
Quoi qu’il en soit, une approche commune est la suivante:
par exemple, imaginez une
GET
demande de/products/widgets
Disons que le secret du client est "OH_HAI_I_IZ_SECRET"
Concaténez le verbe HTTP, l'URL et le secret:
Et prenez un hachage SHA-1 de cela:
Puis envoyez-le, la demande serait donc pour:
Enfin, pour empêcher au moins une autre personne de rejouer des requêtes individuelles, prenez également un horodatage et ajoutez-le aux paramètres et au hachage. par exemple, à l'heure Unix, correspond à 1384987891. Ajoutez cela à la concaténation:
Hache ça:
Et envoyer:
Le serveur vérifiera le hachage et vérifiera également que l'horodatage est actuel (par exemple, dans les 5 minutes pour permettre aux horloges de ne pas être parfaitement synchronisées)
Attention! Puisque vous parlez d'applications mobiles, il y a un risque certain que le téléphone de quelqu'un se trompe d'horloge. Ou le mauvais fuseau horaire. Ou quelque chose. Ajouter du temps au hash va probablement casser certains utilisateurs légitimes, utilisez donc cette idée avec prudence.
la source
Sur Android, vous POUVEZ vérifier que la demande que vous avez reçue a été envoyée depuis votre application.
En bref, lorsque vous téléchargez votre application sur Google, vous la signez avec une clé unique que vous seul connaissez (et google).
Le processus de vérification se passe comme suit:
le blog complet qui l'explique et comment le mettre en œuvre peut être trouvé ici: http://android-developers.blogspot.co.il/2013/01/verifying-back-end-calls-from-android.html
la source
Ok, donc il vaut la peine de mentionner avant de commencer que pour la plupart des applications, cela est excessivement excessif. Dans la plupart des cas d'utilisation, le simple fait de posséder un seul certificat et / ou jeton valide suffit largement. Si cela implique de faire quelque chose de difficile, comme de décompiler votre application, alors même la plupart des pirates informatiques ne s'embêteront pas, à moins que vous ne fournissiez des données de grande valeur. Mais bon, où est le plaisir dans cette réponse?
Vous pouvez donc configurer une cryptographie asymétrique, un peu comme une signature numérique utilisée pour signer des programmes. Chaque application peut ensuite avoir un certificat individuel émis par une seule autorité de certification et vérifié lors de la connexion de votre utilisateur. (soit lors de la première inscription ou lors de la première installation) Lorsque ce certificat est authentifié, vous pouvez alors sécuriser davantage votre application en enregistrant ce certificat comme valide pour un identifiant de périphérique donné (tel que l' ID Android ).
la source
Comme @Morons l'a mentionné dans sa réponse, il est très difficile de vérifier l'entité à l'autre bout de la connexion.
Le moyen le plus simple de fournir un certain niveau d'authenticité est de demander au serveur de vérifier un secret que seule l'entité réelle connaît. Pour un utilisateur, cela pourrait être un nom d'utilisateur et un mot de passe. Pour un logiciel sans utilisateur, vous pouvez intégrer un secret.
Le problème avec ces approches est que vous devez faire confiance au client. Si quelqu'un inverse l'ingénierie de votre application ou vole votre mot de passe, il peut se faire passer pour vous.
Vous pouvez prendre des mesures pour rendre plus difficile l'extraction des informations secrètes en les masquant dans l'exécutable. Des outils tels que ProGuard, qui est un obfuscateur pour Java, peuvent aider à cela. Je ne connais pas autant le principe d’obscurcissement dans d’autres langues, mais il existe probablement des outils similaires. L'utilisation d'une connexion TLS aide à empêcher les personnes d'espionner votre trafic, mais n'empêche pas une attaque MITM. Épingler peut aider à résoudre ce problème.
Je travaille pour une société appelée CriticalBlue (divulgation complète!) Qui propose un produit appelé Approov qui tente de résoudre ce problème de confiance. Il fonctionne actuellement pour Android / iOS et fournit un mécanisme permettant à nos serveurs de vérifier l'intégrité de l'application cliente. Pour ce faire, il demande au client de calculer une réponse à un défi aléatoire. Le client doit calculer la réponse à l'aide d'attributs du package d'application installés qui sont difficiles à simuler et comprend des mécanismes sophistiqués anti-sabotage.
Il renvoie un jeton que vous pouvez ensuite envoyer comme preuve d'authenticité à votre API.
La différence importante avec cette approche réside dans le fait qu'il est possible de désactiver le contrôle d'authenticité sur le client. Si vous le faites, vous n'obtiendrez pas le jeton d'authentification dont vous avez besoin pour vérifier votre application sur le serveur. La bibliothèque est également étroitement liée aux caractéristiques de l'exécutable dans lequel elle se trouve. Il serait donc très difficile de l'intégrer dans une fausse application et de la faire fonctionner.
Tout développeur d’API doit effectuer une analyse coûts / avantages pour déterminer la probabilité que quelqu'un essaie de pirater son API et son coût éventuel. Une simple vérification secrète dans l'application évite les attaques triviales, mais se protéger contre un attaquant plus déterminé est probablement beaucoup plus compliqué et potentiellement coûteux.
la source
SSL sécurisera le canal de communication.
Une connexion réussie émettra un jeton d’authentification sur une connexion chiffrée.
Le jeton d'authentification sera transmis à votre API REST dans toutes les demandes suivantes.
la source
Ce ne serait pas trop sécurisé, mais vous pourriez ajouter une sorte de code secret ou même une signature générique. Inconvénient: il doit être inclus dans l'application, ce qui facilite son obtention si vous savez ce que vous faites.
la source
En fait, vous pouvez utiliser SSL pour authentifier le client et le serveur. Ou, autrement dit, "oui, vous pouvez utiliser des certificats clients".
Vous aurez besoin de ...
L'application mobile peut stocker le certificat où vous voulez. Puisque vous voulez une authentification spécifique à l’application, vous devriez envisager de stocker le certificat dans un emplacement de disque protégé (sous Android, vous pouvez créer une table "config" dans votre base de données SQLite, ainsi qu’une ligne pour votre certificat et une autre pour votre clé privée). .
la source