web-dev-qa-db-fra.com

Comment envoyer un mot de passe en toute sécurité via HTTP en utilisant Javascript en l'absence de HTTPS?

Le problème très basique auquel tous les développeurs sont confrontés: chaque fois que l'utilisateur soumet le formulaire, le mot de passe est envoyé via le réseau et il doit être protégé. Le site pour lequel je développe n'a pas de HTTPS. Le propriétaire ne souhaite pas non plus acheter de certificat SSL, ni s’intéresser à un certificat auto-signé. Je souhaite donc protéger le mot de passe envoyé via HTTP en utilisant Javascript lors de la soumission du formulaire.

Pour les downvoters désireux: Comment envoyer un mot de passe en toute sécurité via HTTP? NE donne PAS de solution sensée et je suis dans une autre situation.

Si j'utilise MD5, on peut inverser cette chaîne de mot de passe. Qu'en est-il du nonce/HMAC? Une bibliothèque Javascript disponible pour cela? Ou avez-vous une suggestion/un indice à aborder? Merci d'avance!

55
Viet

Il n'y a aucun moyen d'envoyer un mot de passe en toute sécurité que l'utilisateur peut vérifier sans SSL.

Bien sûr, vous pouvez écrire du JavaScript qui sécurisera un mot de passe pour une transmission par le biais du hachage ou du cryptage à clé publique. Mais comment l'utilisateur peut-il être sûr que le JavaScript lui-même n'a pas été falsifié par un homme du milieu avant qu'il ne les atteigne, pour envoyer le mot de passe à un attaquant au lieu du site, ou même simplement compromettre la sécurité du algorithme? La seule façon serait pour eux d'être des programmeurs experts et de leur faire inspecter chaque ligne de votre page et de votre script pour vous assurer qu'il est casher avant de taper le mot de passe. Ce n'est pas un scénario réaliste.

Si vous voulez que les mots de passe soient à l'abri des attaques de l'homme du milieu, vous devez acheter un certificat SSL. Il n'y a pas d'autre moyen. Habituez-vous.

Si j'utilise MD5, on peut inverser cette chaîne de mot de passe.

Non ... pas trivialement au moins. Alors que MD5 a des attaques contre lui, c'est un algorithme de hachage et donc irréversible. Il faudrait le forcer brutalement.

Mais encore une fois, un attaquant man-in-the-middle n'a pas besoin de regarder vos MD5. Il peut simplement saboter le JavaScript que vous envoyez à l'utilisateur pour créer les MD5.

77
bobince

La solution ici est de ne pas envoyer du tout le mot de passe. Utilisez défi/réponse.

Dans la forme originale, incluez un grand bloc de texte aléatoire avec une clé. Stockez le texte aléatoire d'origine dans la session en fonction de la clé sur le serveur. Lorsque le client soumet le formulaire, utilisez JS pour hacher le texte aléatoire et le mot de passe ensemble. Envoyez ensuite le nom d'utilisateur, la clé et le texte aléatoire haché au serveur. N'ENVOYEZ PAS le mot de passe. Sur le serveur, utilisez la clé pour rechercher le texte aléatoire d'origine, effectuez la même opération de hachage avec le mot de passe stocké. Si la valeur de hachage du serveur correspond à la valeur de hachage du client, vous savez que le client a entré le bon mot de passe sans jamais envoyer le mot de passe au serveur.

Que le mot de passe soit correct ou non, expirez la clé et le texte aléatoire afin que chacun soit à usage unique.

24
Samuel Neff

Si vous voulez VRAIMENT approfondir cela, regardez le échange de clés Diffie-Hellman qui a été créé pour "permettre à deux parties qui ne se connaissent pas mutuellement d'établir conjointement une clé secrète partagée sur un canal de communication non sécurisé "

Je ne suis pas un expert en cryptographie, donc je ne sais pas vraiment si c'est vraiment sécurisé si un attaquant a à la fois le Client (code source JavaScript) et le mécanisme de transport (Packet sniffer)

11
Michael Stum

Vous pouvez utiliser une implémentation javascript RSA pour crypter le mot de passe avant de l'envoyer. (Voici un exemple de RSA In Javascript .)

Mais je crois que celui-ci et l'utilisation d'une fonction de hachage seront vulnérables à rejouer les attaques . Donc sois prudent.

5
Szere Dyeri

Malheureusement, il n'y aura aucun moyen d'assurer la sécurité d'une demande non cryptée. Toute personne ayant accès à votre javascript sera simplement en mesure de procéder à une rétro-ingénierie/falsification et toute personne possédant un renifleur de paquets pourra regarder le trafic non crypté. Ensemble, ces deux faits signifient:

Pas de SSL? Pas de sécurité.

4
rfunduk

Si vous n'avez pas accès à SSL, MD5 devrait être suffisant pour empêcher la découverte accidentelle de mots de passe (comme dans un fichier journal réseau ou autre). Tout le reste serait une perte de temps. Assurez-vous simplement que l'application ne donne pas accès à des informations sensibles (par exemple, les numéros de carte de crédit, les antécédents médicaux, etc.).

Comme d'autres commentateurs l'ont suggéré, un attaquant sérieux pourra briser tout type de sécurité sur la page. Même SSL est une petite barrière car la plupart des utilisateurs utilisent des mots de passe faciles à deviner, réutilisent les mêmes mots de passe partout, donneront leur mot de passe à quiconque le demande, ou peuvent être amenés à abandonner leur mot de passe par une page copiée ou "tech" soutien "appel téléphonique.

1
Brian

Toute transmission que vous avez sera en clair; c'est-à-dire que sans SSL, vos informations critiques seront exposées. Il vaut la peine de discuter de ce point avec le propriétaire du site. En d'autres termes, il est préférable de prendre les mesures nécessaires pour renforcer votre transmission de données, et SSL est l'une des étapes basiques et bon marché que vous pouvez prendre.

1
David Robbins

je ne pense pas que le problème ici soit la technologie, mais comment vous expliquez l'importance du SSL. Fournissez-leur du matériel de lecture fiable, je suis sûr qu'il y en a beaucoup sur le Web.

1
Martin Ongtangco

La solution nécessite que le client puisse crypter le mot de passe à l'aide d'une clé de cryptage secrète connue niquement pour le client et le serveur.

SSL accomplit cela en exigeant que le serveur et le navigateur Web client aient leur propre paire de clés publique/privée asymétrique, qu'ils utilisent pour crypter et transmettre une clé de session aléatoire entre eux. Le reste de la conversation utilise ensuite cette clé de session sécurisée.

Vous vous demandez donc comment résoudre le même problème que SSL sans l'avantage d'avoir une clé secrète connue niquement pour le client et le serveur. Je ne suis pas un expert, mais il semble que cela ne puisse pas être fait, ou du moins pas facilement.

1
David R Tribble

Comme mentionné, rien de tout cela n'est sécurisé contre serveur usurpation d'identité, car cela nécessite une capacité à faire confiance au Javascript côté client. Mais si nous sommes sûrs que le serveur ne peut pas être usurpé (certificat signé, signature de hachage immunisée contre l'extension de longueur, etc.) mais pas que la connexion est immunisée contre les écoutes, voici comment je ' d le mettre en œuvre.

Je pense que le moyen le plus sûr est, au lieu de stocker H (mot de passe), où H est votre fonction de hachage de choix, stockez g ^ H (mot de passe), c'est-à-dire utiliser le mot de passe comme clé privée pour l'échange de clés Diffie-Hellman. (Vous devriez aussi probablement utiliser un g aléatoire pour différents utilisateurs - cela devient votre sel.) Ensuite, pour vérifier, vous générez un nonce b, envoyez l'utilisateur g ^ b et calculez (g ^ H (mot de passe)) ^ b. L'utilisateur n'a pas besoin de connaître g - il n'a besoin que de calculer (g ^ b) ^ H (mot de passe) = (g ^ H (mot de passe)) ^ b. Maintenant, vous avez un nombre que les deux parties connaissent iff l'utilisateur a entré le bon mot de passe, et la construction d'une preuve de connaissance zéro de la réponse au défi basée sur la connaissance du numéro correct est triviale, tandis que le nombre aléatoire utilisé comme La "clé privée" du serveur rend l'approche immunisée contre les attaques de réexécution.

0
NXTangl

- Anglais - je pense à quelque chose, mais je ne sais pas si cela pourrait être vraiment sécurisé. Si vous pouvez mettre votre formulaire dans un fichier php, vous pouvez créer un algorithme pour créer une chaîne basée sur le temps ou dans autre chose, puis mettre cette chaîne dans votre html.

Lorsque l'utilisateur saisit un mot de passe dans un champ de saisie de mot de passe, lorsque vous le déboguez, vous ne pouvez pas voir la valeur saisie par l'utilisateur, donc avant d'envoyer les informations par la poste ou d'obtenir, vous pouvez utiliser l'utilisateur du mot de passe comme indice pour chiffrer la chaîne chiffrée au préalable. généré, puis envoyé juste après le mot de passe tapé par l'utilisateur.

De cette façon, les attaquants n'ont pas tout à l'intérieur du code js, ils auront donc besoin de découvrir l'algorithme que vous créez pour le déchiffrer.

Ce n'est qu'une idée, donc si vous pouvez me dire comment cela ne peut pas être sûr, je l'apprécierais.

- Espagnol - Se me acaba de ocurrir algo que puede servir, pero no se si realmente sea algo seguro. Par medio de php puedes generar un algoritmo que cree un string en base al timestamp o algo más, y después colocar esta cadena en el html.

Remarque que cuando alguien escribe una contraseña en un campo input tipo password, con un debug no se puede ver el valor que tecleo el usuario (no se si exista manera pero no quise investigar más), asi que podemos utilizar la contraseña que el usuario escribió como palabra clave para encriptar la cadena de texto que previamente habiamos generado con php, por medio de un algoritmo en JS. Sería algo así como encriptar lo encriptado. Posteriormente lo que estariamos enviado no sería la contraseña tecleada, si no esta última cadena resultante.

Buscando un contra, lo único que se me ocurra es que el atacante tendrá que dedicarle mucho tiempo para tratar de encontrar el agoritmo que creamos por medio de php y poder decriptar la cadena final, o tendrá que hackear el servidor para acceder al php y obtener el algoritmo.

Esto es solo una idea, por lo que si pueden decirme como esto puede no ser seguro, se los agradecería.

0
eduardossmx