Question:
Comment sécuriser les mots de passe via HTTP?
FireCubez
2018-11-09 19:57:16 UTC
view on stackexchange narkive permalink

Dites que mon mot de passe est abc . Je veux l'envoyer au serveur via HTTP.

Je pourrais l'envoyer en texte clair et laisser le serveur le hacher et le comparer aux entrées de sa base de données, mais alors quiconque peut voir le trafic sur cette connexion verrait le mot de passe en texte brut.

Alors je pourrais le hacher côté client et laisser le serveur le comparer sans hachage puisqu'il est déjà haché (ou le serveur pourrait même doubler le hachage, mais aucune différence dans cette situation). Mais là encore, quiconque peut voir le trafic verrait le mot de passe haché, puis enverrait le mot de passe haché au serveur et le serveur l'accepterait.

Comment envoyer des mots de passe via HTTP? Dois-je implémenter un algorithme de cryptage tel que le cryptage à clé publique RSA? Ou est-ce impossible?

La méthode devrait être utilisable dans n'importe quel navigateur.

Pourquoi ne pouvez-vous pas simplement utiliser TLS?Il n'y a vraiment pas d'autre moyen de le faire en toute sécurité.
@AndrolGenhald Je pourrais, c'est juste une preuve de concept.S'il n'y a pas d'autre moyen de le faire en toute sécurité, c'est la réponse que je cherchais.Vous devriez l'afficher comme réponse
Vous n'avez pas besoin de TLS natif - vous pourriez, en théorie, implémenter TLS sur HTTP - mais ce serait loin d'être pratique.
@AndrolGenhald Il n'y a aucune bonne raison de ne pas utiliser TLS, mais je crois qu'il existe de nombreuses autres façons de le faire en toute sécurité.Par exemple, on pourrait tunneler http via ssh.
Essayez peut-être d'utiliser ECDHE pour échanger les clés en toute sécurité?
@emory L'affiche a précisé que le contexte est la communication entre le navigateur Web et le serveur HTTP, et non une application personnalisée vers un serveur personnalisé.
Est-ce un problème réel auquel vous êtes confronté ou simplement une expérience de pensée?
@whatsisname J'ai déclaré que dans un commentaire précédent, c'est juste une expérience
Bien que je déteste quand vous demandez à A et que les gens répondent "utilisez simplement B", je dois être d'accord avec les nombreuses réponses "utilisez simplement TLS" car c'est la manière la plus simple de résoudre un problème pratique.Maintenant, vous avez déclaré qu'il ne s'agissait pas d'un problème pratique mais "juste pour l'expérimentation", vous voudrez peut-être vous renseigner sur les [protocoles zéro connaissance] (https://en.wikipedia.org/wiki/Zero-knowledge_proof)tu veux.
L'implémentation de mot de passe MSN Messenger d'origine a pris en compte ce scénario.Le serveur vous a envoyé un "sel" et vous avez haché votre mot de passe à l'aide de celui-ci et renvoyé le hachage au serveur.Comme le serveur connaissait votre mot de passe, il pouvait effectuer le même calcul.Le serveur était chargé de s'assurer qu'il ne réutilisait pas les sels
FWIW, même si vous parvenez à transférer les mots de passe en toute sécurité, vous n'aurez rien accompli.Le reste de la session n'est pas chiffré, il peut facilement être volé ou modifié.Même si vous pouvez prouver en toute sécurité "Vous êtes Bob", au moment où cela se produit, Alice peut voler votre session et "être Bob" aussi longtemps qu'elle le souhaite.
@curiousguy Si OP a exécuté `ssh -L 127.0.0.1:8080:intra.example.com:80 gw.example.com` puis accédé à http://127.0.0.1:8080, la connexion sera cryptée et les mots de passe sécurisés.(1) Cela suppose que OP peut ssh dans gw.example.com et (2) peut-être que le serveur Web ne répond pas aux demandes locales.Cet exemple peut / peut ne pas fonctionner pour OP, mais l'affirmation selon laquelle TLS est le seul moyen est erronée.
@emory N'est-ce pas _en effet_ en utilisant TLS, mais simplement en demandant à `ssh` de le faire plutôt que de l'implémenter directement dans le client?Et la connexion de `gw.example.com` au vrai serveur Web ne serait-elle pas encore vulnérable aux écoutes clandestines?
@TripeHound Je recommanderais simplement d'utiliser TLS et de ne pas s'inquiéter de ces problèmes.Mais s'il utilise en fait TLS mais que ssh le fasse plutôt que l'implémenter directement dans le client, alors la connexion au vrai serveur Web ne serait pas vulnérable aux écoutes clandestines.
Neuf réponses:
tim
2018-11-09 20:08:48 UTC
view on stackexchange narkive permalink

Vous ne pouvez pas.

Pour envoyer des informations en toute sécurité via un canal non sécurisé, vous avez besoin d'un cryptage.

Le chiffrement symétrique est désactivé, car vous devez d'abord transporter la clé, ce que vous ne pouvez pas faire en toute sécurité sur un canal non sécurisé [*].

Cela vous laisse avec la clé publique cryptographie. Vous pouvez bien sûr rouler le vôtre, mais vous ne voulez pas être un Dave, donc c'est fini, ce qui vous laisse avec HTTPS.

[*] Vous pouvez bien sûr essayer d'utiliser un canal sécurisé pour échanger la clé, par exemple l'échange physique d'une clé. Ensuite, vous pouvez utiliser une clé secrète crypto, comme Kerberos.

Tu ne pourrais pas le hacher deux fois?Une fois côté client, une fois sur le serveur?
@NathanMerrill - [Le hachage du mot de passe côté client fait simplement du hachage le mot de passe] (https://security.stackexchange.com/questions/8596/https-security-should-password-be-hashed-server-side-or-côté client) (absence de schéma pour inclure des informations supplémentaires).Cependant, seule la sécurisation du mot de passe est sans valeur - vous devez au moins authentifier le ** canal **, sinon un attaquant peut se faire passer pour les deux extrémités de la conversation, même sans connaître le mot de passe.
C'est trompeur.Oui, vous pouvez.Cette question demande comment sécuriser les mots de passe lorsque vous ne pouvez pas utiliser HTTP.Une mauvaise politique d'entreprise, un pare-feu mal configuré peuvent tous forcer l'utilisation de HTTP.Dans de telles situations, l'échange de certificats (IPsec TLS SCRAM, etc.) via un canal latéral est possible et devrait être la réponse.Répondez à la question au lieu de donner des conseils qui n'ont pas été recherchés.
@noɥʇʎԀʎzɐɹƆ J'ai mentionné qu'il existe des alternatives lorsqu'un canal latéral sécurisé peut être utilisé (ce qui est requis pour les alternatives mentionnées dans d'autres réponses).Mais ce n'est pas vraiment le sujet de la question ("La méthode devrait être utilisable dans n'importe quel navigateur").Il y a certainement des cas d'utilisation pour ces alternatives, mais «nous ne pouvons pas utiliser HTTPS parce que notre infrastructure est trop cassée» ne devrait pas en faire partie.
Je suis d'accord avec le point principal - cela ne peut pas être fait.Mais j'ajouterais que même si vous êtes Dave et roulez votre propre crypto, cela ne vous aiderait pas.Le code qui effectue le cryptage est livré via HTTP et peut donc être falsifié.
AndrolGenhald
2018-11-09 20:09:53 UTC
view on stackexchange narkive permalink

TLS est vraiment le seul moyen de le faire.

Mais que se passe-t-il si je le crypte avec JavaScript?

L'attaquant peut modifier le JavaScript que vous envoyer au client, ou simplement injecter leur propre JavaScript qui enregistre toutes les informations saisies.

Ensuite, j'utiliserai CSP et SRI pour empêcher l'ajout de scripts et la modification de mes propres scripts.

Heureux que vous utilisiez des outils modernes pour aider à protéger votre site, mais le SRI dans un contexte non sécurisé ne protège vraiment que contre la compromission d'une ressource externe. Un attaquant peut simplement modifier les en-têtes CSP et les balises SRI.

Il n'y a vraiment aucun moyen de faire cela sans utiliser le chiffrement depuis le début, et la seule façon standard de le faire est d'utiliser TLS.

Melanie
2018-11-10 00:01:01 UTC
view on stackexchange narkive permalink

Bien que j'accepte que vous utilisiez HTTPS, vous pouvez le rendre encore plus sécurisé en utilisant le mécanisme d'authentification Salted Challenge Response (SCRAM, voir RFC 5802) pour l'échange d'authentification réel.

Ce n'est pas trivial à mettre en œuvre, mais l'essentiel est que, plutôt que d'envoyer le mot de passe au serveur, vous envoyez la preuve au serveur que vous connaissez le mot de passe. Puisque la dérivation de la preuve utilise un nonce du client et du serveur, ce n'est pas quelque chose qui peut être réutilisé par un attaquant (comme le serait l'envoi du hachage lui-même).

Cela présente quelques avantages supplémentaires à utiliser HTTPS avec l'authentification de base que vous décrivez:

  1. Le serveur ne voit jamais réellement votre mot de passe lorsque vous vous connectez. Si quelqu'un a réussi à insérer un code malveillant sur le serveur, il ne saura toujours pas quel est votre mot de passe .
  2. S'il y a un bogue dans l'implémentation HTTPS (pensez Heartbleed), les attaquants ne pourront toujours pas acquérir votre mot de passe. Parce que, même une fois que TLS est contourné, le mot de passe n'est pas disponible.
  3. Si, pour une raison quelconque, vous ne pouvez pas utiliser HTTPS, c'est mieux que d'envoyer le mot de passe en clair. Un attaquant ne pourra pas deviner votre mot de passe en fonction de l'échange. Cela dit, vous devriez toujours utiliser HTTPS, car la défense en profondeur est meilleure.

Veuillez noter que cela n'est sécurisé que si le client est capable d'effectuer le SCRAM calculs sans télécharger de code depuis le serveur. Vous pouvez fournir un gros client, ou les utilisateurs peuvent être en mesure d'écrire leur propre code qu'ils contrôlent. Le téléchargement du code SCRAM via HTTP donnerait à un attaquant la possibilité de modifier le code SCRAM pour envoyer le mot de passe en texte clair, ou l'exposer autrement.

Vous pouvez le faire en toute sécurité avec un gros client (une application de bureau ou mobile) qui est distribué de manière sûre.Cependant, avec un client léger intégré au navigateur, le code client lui-même est également fourni via HTTP, et comme l'a souligné @AndrolGenhald, les attaquants du milieu peuvent l'intercepter et le modifier pour leur envoyer le mot de passe.
@Zoltan C'est très vrai, merci pour la clarification.La question initiale ne précise pas s'ils ont besoin d'un client léger ou gros, donc ma réponse ne s'appliquerait pas dans tous les cas.Mais même sur HTTP, je pense que cela offre une sécurité supplémentaire.L'attaque est passée de la simple surveillance du trafic à la modification du code.Rien d'insurmontable, donc ce ne serait pas sûr, mais peut-être moins mauvais?Et je pense qu'avoir à la fois HTTPS et SCRAM est très bénéfique.
Si vous acceptez, vous pouvez envisager de mentionner cette restriction dans votre réponse.Sinon, j'aime beaucoup votre réponse car la réponse challange a été ma première pensée aussi et aucune des autres réponses ne l'a mentionnée.
Merci, j'ai mis à jour ma réponse.Faites-moi savoir si vous pensez que cela pourrait nécessiter des clarifications supplémentaires!
Cela me semble bien, merci, a voté pour.Vous devez cependant supprimer la partie "Merci à Zoltan", car les expressions de politesse comme les salutations, la signature et les remerciements sont découragées dans les questions et réponses sur les sites Stack Exchange afin de se concentrer sur le contenu.Oh, et bienvenue sur Stack Exchange au fait!:)
@Melanie Vous avez tout à fait raison de dire que même avec juste HTTP, c'est mieux.Il existe des attaquants capables uniquement d'attaques passives.Cela étant dit, il n'y a aucune raison de ne pas utiliser HTTPS de nos jours lorsqu'il est gratuit.
SCRAM exige-t-il que le mot de passe soit stocké de manière récupérable sur le serveur?Ou peut-il encore être salé + haché
@IanF1 Le serveur a seulement besoin de connaître un Hash du mot de passe.De plus, tous les navigateurs que je connais implémentent un mécanisme similaire: [HTTP Digest Authentication] (https://en.wikipedia.org/wiki/Digest_access_authentication), donc même avec un client léger, on peut utiliser cette méthode.D'un autre côté, le condensé HTTP est basé sur les hachages MD5 obsolètes, mais je ne suis pas sûr de son insécurité à cause de cela (MD5 n'est pas cassé pour chaque application).
@Zoltan, J'ai supprimé le merci.Bien que je n'aime pas ne pas donner de crédit là où c'est dû, je suppose que c'est ici dans les commentaires.Merci encore!
@Jost Utiliser MD5 (ou une fonction basée sur l'itération MD5, ou une composition avec un sel ou un nom) pour stocker ou vérifier les mots de passe n'est ** pas plus cassé aujourd'hui que jamais **: le calcul de MD5 ou de toute itération de MD5 peut 't être simplifié et MD5 ^ 1000 a encore besoin de 1000 itérations du calcul, et il n'y a pas de meilleur moyen de trouver quel x satisfait MD5 ^ 1000 (x) = y que d'essayer différentes valeurs de x, ou des méthodes basées sur des listes précalculées, ce qui estégalement la meilleure méthode pour SHA1 ou des fonctions de hachage plus modernes.Aucune avancée théorique ou pratique n'a été faite ici.
Polynomial
2018-11-10 00:31:25 UTC
view on stackexchange narkive permalink

Vous devez absolument déployer TLS dans ce cas.

Si vous décidez d'essayer d'inventer un système de sécurité de transport sur HTTP, vous finirez par implémenter de toute façon un sous-ensemble de la fonctionnalité TLS. Il y a de nombreux pièges à prendre en compte lors de la conception et de la mise en œuvre d'un tel système, qui sont encore amplifiés lorsque vous choisissez d'essayer d'implémenter le système avec un langage qui n'offre pas beaucoup de fonctionnalités de sécurité.

Même si vous avez implémenté une implémentation correcte d'un protocole cryptographique en JavaScript (ce qui est déjà un gros défi), vous ne pouvez pas compter sur cette implémentation résistante aux attaques de timing, et le tout se brise si quelqu'un a des scripts désactivés (par exemple avec NoScript).

En règle générale, vous devez choisir l'implémentation qui se compose des composants les plus simples, les mieux compris et les plus fiables qui vous obligent à écrire le moins de code critique pour la sécurité. Pour citer Andrew Tannenbaum:

Un grand nombre de problèmes (dans la sécurité des applications) sont causés par des logiciels bogués, qui se produisent parce que les fournisseurs ajoutent de plus en plus de fonctionnalités à leurs programmes, ce qui signifie inévitablement plus de code et donc plus de bogues.

Brian Williams
2018-11-09 22:03:34 UTC
view on stackexchange narkive permalink

Dois-je implémenter un algorithme de chiffrement comme le chiffrement à clé publique RSA?

Si vous envisagez d'essayer cela, vous pouvez aussi bien faire le plein kilomètre et utiliser HTTPS. Etant donné que vous ne semblez pas être un expert, le chiffrement «roulant vous-même» aura sans aucun doute des erreurs de mise en œuvre qui le rendront non sécurisé.

Pierre del Perugia
2018-11-10 15:38:45 UTC
view on stackexchange narkive permalink

C'est en fait tout à fait possible.

Le mot de passe doit être haché côté client, mais pas avec une fonction statique. La méthode suivante utilise deux étapes et s'inspire de l ' authentification d'accès Digest:

REMARQUE: Le serveur conserve un HMAC du mot de passe et du code correspondant Clé ( Digest );

  1. Le client commence par demander un nonce au serveur, le serveur renvoie la Clé et le Nonce
  2. Client calcule: HMAC (HMAC ( Mot de passe , Clé ), Nonce ) et l'envoie au serveur;
  3. Le serveur calcule: HMAC ( Digest , Nonce ) et le compare à la valeur reçue.

Cela vous protège contre la relecture.

Le principal intérêt que je vois n'est pas une protection contre les écoutes clandestines, mais d'être complètement sûr que le mot de passe en clair ne sera pas stocké sur le serveur, même pas dans un journal système (voir Twitter ou GitHub).

Remarque: HMAC peut être remplacé par PBKDF2.

Ensuite, un attaquant peut injecter du code pour obtenir le mot de passe directement à partir de ``.Une idée folle: "Malheureusement, il est * juste un peu * difficile de prendre en charge HTTPS sur les adresses IP réservées. Veuillez [exécuter ce code sur votre terminal] (https://stackoverflow.com/a/7285256) et collez le résultat HMAC.. "(bien sûr, désactivez le copier-coller pour éviter le pastejacking à long terme).
CBHacking
2018-11-10 16:42:21 UTC
view on stackexchange narkive permalink

Il existe en fait un moyen d'authentifier un utilisateur via une connexion non sécurisée: le protocole SRP (Secure Remote Password). SRP est spécifiquement conçu pour permettre à un client de s'authentifier auprès d'un serveur sans qu'un attaquant Man-in-the-Middle puisse capturer le mot de passe du client, ou même rejouer l'authentification pour usurper ultérieurement l'identité du client, que l'authentification ait réussi ou non. En outre, une authentification réussie avec SRP crée une clé secrète partagée que le client et le serveur connaissent, mais pas un MitM. Cette clé secrète pourrait être utilisée pour le cryptage symétrique et / ou les HMAC.

Cependant, il existe un certain nombre de limitations de SRP:

  1. L'utilisateur doit s'être enregistré dans un mode, car le processus d'enregistrement nécessite la transmission d'un matériel équivalent au mot de passe (bien que le serveur n'ait pas besoin de le stocker).
  2. Bien qu'il soit sûr de tenter une connexion SRP avec un serveur non approuvé (c'est-à-dire n'exposera pas votre mot de passe à ce serveur, et vous serez en mesure de dire que le serveur n'avait pas votre mot de passe dans sa base de données), Il n'est pas sûr de charger une page Web de connexion à partir d'un serveur non approuvé (cela pourrait envoyer une page qui capture chaque frappe et l'envoie quelque part).
  3. Bien que l'authentification réussie via SRP génère une clé secrète partagée sécurisée, le code pour utiliser réellement cette clé dans une application Web doit être chargé à partir de un serveur, et un attaquant pourrait altérer ce code pour voler la clé symétrique et apporter des modifications aux requêtes et réponses.

En d'autres termes, alors que SRP peut être utile dans les situations où vous avez un client de confiance qui n'a pas besoin de télécharger son code via la connexion non sécurisée et que vous disposez également d'un autre moyen sécurisé pour enregistrer le ou les utilisateurs, SRP ne convient pas à une application Web. Les applications Web téléchargent toujours leur code à partir du serveur, donc si la connexion au serveur n'est pas sécurisée, un MitM (ou un autre attaquant du réseau, par exemple quelqu'un qui spoofing DNS) peut injecter un code malveillant dans l'application Web et il n'y a rien que vous la victime peut y remédier. Une fois que ce code est là, il peut capturer n'importe quel mot de passe ou d'autres données que vous entrez, voler n'importe quelle clé générée et falsifier toutes les demandes que vous envoyez ou les réponses que vous recevez sans que vous le sachiez.

Christopher Schultz
2018-11-11 04:51:56 UTC
view on stackexchange narkive permalink

Il est certainement possible d'envoyer un mot de passe en toute sécurité en utilisant HTTP. Il existe même une norme pour cela. Il s'appelle HTTP-Digest et il est défini dans la RFC 7616. Cela fait partie de la spécification HTTP depuis un certain temps. Il a été conçu à l'origine pour n'utiliser que l'algorithme MD5 message-digest ("hashing"), mais les révisions ultérieures de la norme permettent au client et au serveur de négocier l'algorithme à utiliser.

Malheureusement, il y a beaucoup de problèmes avec HTTP-digest et le plus flagrant d'entre eux est que le serveur doit avoir le mot de passe en clair . Ainsi, bien qu'il soit possible de communiquer des mots de passe en toute sécurité à l'aide de HTTP, il n'est pas possible de stocker en toute sécurité les mots de passe sur le serveur tout en l'utilisant. Donc, fondamentalement, ce n'est pas utile.

Comme d'autres l'ont dit, il serait préférable d'implémenter TLS car il résout plusieurs problèmes en même temps, et il est assez compatible.

Richard N
2018-11-13 03:55:03 UTC
view on stackexchange narkive permalink

Comme d'autres l'ont dit TLS! TLS! TLS! (et avec une longueur de clé décente aussi)

Mais si vous devez utiliser HTTP et n'importe quel serveur à implémenter, est-ce pour un usage programmatique ou humain? Si pour un usage humain, recherchez-vous l'authentification de base ou basé sur un formulaire? Et vos utilisations sont-elles capables d'appliquer un peu de logique, par exemple. pas pour joe public à utiliser. Est-ce que quelque chose d'autre doit être protégé, ou juste le mot de passe lui-même?

Si c'est le cas, vous pourrez peut-être regarder:

  • Utilisez un pad / générateur de mot de passe à usage unique (les porte-clés RSA ne sont pas bon marché, et si vous avez ce genre d'argent à dépenser, vous pouvez vous permettre TLS)
  • Une autre authentification à 2 facteurs comme les SMS (pas sans ses propres problèmes).
  • Un simple mécanisme de défi / réponse pour masquer le mot de passe, par exemple la page affiche deux chiffres dessus dans le texte (pas de façon flagrante non plus), l'utilisateur doit démarrer le mot de passe avec un calcul simple comme la différence entre les deux nombres ajoutés à chaque chiffre d'un code PIN, peut-être avec des éléments aléatoires avant et / ou et après, par exemple 98634572dkkgdld. La modification des numéros de défi devrait arrêter les attaques de relecture qui ne sont pas tentées instantanément, mais si un attaquant peut capturer suffisamment de tentatives, il peut être en mesure de résoudre le problème. Vous ne pouvez pas non plus mettre de logique d'obscurcissement dans un script destiné à l'utilisateur, car cela sera vu et si le schéma est trop complexe, vos utilisateurs vous détesteront encore plus.

Cependant, avec TLS, les certificats sont bon marché (même gratuits) de nos jours, donc les schémas d'obfuscation compliqués n'ont plus aucune raison d'exister.



Ce Q&R a été automatiquement traduit de la langue anglaise.Le contenu original est disponible sur stackexchange, que nous remercions pour la licence cc by-sa 4.0 sous laquelle il est distribué.
Loading...