135 votes

Comment envoyer un mot de passe de manière sécurisée via HTTP ?

Si, sur un écran de connexion, l'utilisateur soumet un formulaire avec son nom d'utilisateur et son mot de passe, le mot de passe est envoyé en texte clair (même avec POST, corrigez-moi si je me trompe).

La question est donc de savoir quel est le bon moyen de protéger l'utilisateur et son mot de passe contre un tiers qui pourrait écouter les données de communication.

Je sais que HTTPS est la solution au problème, mais existe-t-il un moyen d'assurer au moins un certain niveau de sécurité en utilisant le protocole HTTP standard (demande POST) ? (peut-être en utilisant javascript d'une manière ou d'une autre)

EDIT J'ai peut-être omis des choses importantes.

Ce dont je parlais était une page - c'est-à-dire une page de connexion générée par PHP, qui est bien sûr envoyée à l'utilisateur dans une requête HTTP GET sous forme de fichier HTML. Il n'y a pas (@Jeremy Powel) de connexion établie entre le serveur et le client, je ne peux donc pas créer un tel protocole de handshaking. Et je veux que le processus complet soit transparent pour l'utilisateur - il veut soumettre un mot de passe, pas s'occuper de cryptographie.

Merci.

89voto

Jeremy Powell Points 1840

L'utilisation du protocole HTTP avec SSL vous facilitera grandement la vie et vous pourrez être tranquille : des personnes très intelligentes (plus intelligentes que moi en tout cas !) ont examiné de près cette méthode de communication confidentielle pendant des années.

14voto

Jeremy Powell Points 1840

Vous pouvez utiliser un système de réponse par défi. Supposons que le client et le serveur connaissent tous deux un secret S. Le serveur peut alors s'assurer que le client connaît le mot de passe (sans le divulguer) de la manière suivante :

  1. Le serveur envoie un nombre aléatoire, R, au client.
  2. Le client renvoie H(R,S) au serveur (où H est une fonction de hachage cryptographique, comme SHA-256).
  3. Le serveur calcule H(R,S) et le compare à la réponse du client. S'ils correspondent, le serveur sait que le client connaît le mot de passe.

Edit :

Il y a un problème ici avec la fraîcheur de R et le fait que HTTP est sans état. On peut gérer ce problème en demandant au serveur de créer un secret, appelé Q, qui seul le serveur sait . Ensuite, le protocole se déroule comme suit :

~~

  1. Le serveur génère un nombre aléatoire R. Il envoie ensuite au client H(R,Q) (qui ne peut pas être falsifié par le client).
  2. Le client envoie R, H(R,Q), calcule H(R,S) et renvoie le tout au serveur (où H est une fonction de hachage cryptographique, comme SHA-256).
  3. Le serveur calcule H(R,S) et le compare à la réponse du client. Puis il prend R et calcule (à nouveau) H(R,Q). Si la version du client de H(R,Q) et H(R,S) correspond au nouveau calcul du serveur, ce dernier considère que le client est authentifié.

~~

À noter que, puisque H(R,Q) ne peut pas être falsifié par le client, H(R,Q) agit comme un cookie (et pourrait donc être implémenté réellement comme un cookie).

Une autre édition :

La modification précédente du protocole est incorrecte car toute personne ayant observé H(R,Q) semble être capable de le rejouer avec le bon hachage. Le serveur doit se souvenir des R qui ne sont plus frais. Je mets cette réponse en CW pour que vous puissiez la modifier et trouver quelque chose de bien.

12voto

Calmarius Points 2626

Si votre hébergeur le permet, ou si vous devez traiter des données sensibles, utilisez HTTPS, point final. (La loi l'exige souvent).

Sinon, si vous voulez faire quelque chose par HTTP. Je ferais quelque chose comme ça.

  1. Le serveur intègre sa clé publique dans la page de connexion.
  2. Le client remplit le formulaire de connexion et clique sur "soumettre".
  3. Une requête AJAX obtient du serveur l'horodatage actuel.
  4. Côté client, le script concatène les informations d'identification, l'horodatage et un sel (haché à partir de données analogiques, par exemple les mouvements de la souris, les événements de pression sur les touches), et les chiffre en utilisant la clé publique.
  5. Soumet le hachage résultant.
  6. Le serveur décrypte le hash
  7. Vérifie si l'horodatage est suffisamment récent (permet une courte fenêtre de 5-10 secondes seulement). Rejette le login si l'horodatage est trop ancien.
  8. Stocke le hachage pendant 20 secondes. Rejette le même hachage pour la connexion pendant cet intervalle.
  9. Authentifie l'utilisateur.

De cette façon, le mot de passe est protégé et le même hachage d'authentification ne peut pas être rejoué.

À propos de la sécurité du jeton de session. C'est un peu plus difficile. Mais il est possible de rendre un peu plus difficile la réutilisation d'un jeton de session volé.

  1. Le serveur définit un cookie de session supplémentaire qui contient une chaîne aléatoire.
  2. Le navigateur renvoie ce cookie lors de la prochaine demande.
  3. Le serveur vérifie la valeur dans le cookie, si elle est différente, il détruit la session, sinon tout va bien.
  4. Le serveur place à nouveau le cookie avec un texte différent.

Ainsi, si le jeton de session est volé et qu'une demande est envoyée par quelqu'un d'autre, la session sera détruite lors de la prochaine demande de l'utilisateur original. Ainsi, si l'utilisateur navigue activement sur le site et clique souvent sur des liens, le voleur n'ira pas loin avec le jeton volé. Ce schéma peut être renforcé en exigeant une autre authentification pour les opérations sensibles (comme la suppression d'un compte).

À propos de la mise en œuvre : RSA est probablement l'algorithme le plus connu, mais il est assez lent pour les clés longues. Je ne sais pas quelle serait la vitesse d'une implémentation PHP ou Javascript. Mais il existe probablement des algorithmes plus rapides.

4voto

hexafraction Points 16201

J'utiliserais un système d'échange de clés Diffie-Hellman côté serveur et côté client avec AJAX ou des soumissions multiples de formulaires (je recommande la première solution), bien que je ne voie pas de bonnes implémentations de ce système sur Internet. N'oubliez pas qu'une bibliothèque JS peut toujours être corrompue ou modifiée par MITM. Le stockage local peut être utilisé pour aider à combattre cela, dans une certaine mesure.

1voto

Rook Points 34698

HTTPS est si puissant parce qu'il utilise une cryptographie asymétrique. Ce type de cryptographie vous permet non seulement de créer un tunnel crypté, mais aussi de vérifier que vous parlez à la bonne personne, et non à un pirate.

Voici le code source Java qui utilise le chiffrement asymétrique RSA (utilisé par PGP) pour communiquer : http://www.hushmail.com/services/downloads/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X