Comment envoyer mot de passe en toute sécurité 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 clair (même avec POST, corriger moi si je me trompe).
la question est donc de savoir quelle est la bonne manière de protéger l'utilisateur et son mot de passe contre le tiers qui pourrait espionner les données de communication?
je suis conscient que HTTPS est une solution au problème, mais est-il possible d'assurer au moins un certain niveau de sécurité utilisant le protocole HTTP standard (POST request)? (peut-être en utilisant javascript d'une certaine façon)
EDIT J'ai peut-être laissé de côté certaines choses importantes.
ce dont je parlais était une page - qui est la page de connexion générée par PHP, qui est bien sûr envoyé à l'utilisateur dans la demande HTTP GET en tant que fichier HTML. Il n'y a pas de connexion (@Jeremy Powel) établie entre le serveur et le client donc je ne peux pas créer un tel protocole de handshaking. Et Je vouloir que le processus complet soit transparent pour l'utilisateur - il veut soumettre un mot de passe, pas traiter de la cryptographie.
Merci.
8 réponses
L'utilisation de HTTP avec SSL rendra votre vie beaucoup plus facile et vous pouvez vous reposer à l'aise les gens très intelligents (plus intelligents que moi au moins!) ont examiné attentivement cette méthode de communication confidentielle pendant des années.
authentification Sécurisée est un vaste sujet. En un mot, comme @jeremy-powell l'a mentionné, il est toujours préférable d'envoyer des justificatifs d'identité par HTTPS plutôt que par HTTP. Cela éliminera beaucoup de maux de tête liés à la sécurité.
Les certificatsTSL/SSL sont assez bon marché de nos jours. En fait, si vous ne voulez pas dépenser d'argent du tout, il ya un gratuit letsencrypt.org - autorité de certification automatisée.
Vous pouvez aller plus loin et utiliser caddyserver.com qui appelle letsencrypt en arrière-plan.
maintenant, une fois que nous avons obtenu HTTPS hors du chemin...
vous ne devez pas envoyer le login et le mot de passe via Post payload ou obtenir des paramètres. Utilisez plutôt un en-tête D'autorisation (Basic access authentication scheme), qui est construit comme suit:
- le nom d'utilisateur et le mot de passe sont combinés dans une chaîne séparée par un côlon, par exemple: Nom d'utilisateur: mot de passe
- la chaîne résultante est encodée en utilisant la variante RFC2045-MIME de Base64, sauf non limitée à 76 char/ligne.
- La méthode d'autorisation et d'un espace c'est à dire "de Base" est alors mettez avant la chaîne encodée.
cela peut sembler un peu compliqué, mais il est pas. Il y a beaucoup de bonnes bibliothèques qui offrent cette fonctionnalité pour vous sortir de la boîte.
il y a quelques bonnes raisons d'utiliser un en-tête D'autorisation
- C'est un " standard
- , C'est simple, une fois que vous apprendre à les utiliser)
- Il vous permet de vous connecter à l'URL, comme ceci:
https://user:password@your.domain.com/login
(Chrome, par exemple convertira automatiquement enAuthorization
en-tête)
IMPORTANT:
Comme l'a souligné @zaph dans son commentaire ci-dessous, envoyer des informations sensibles comme requête GET n'est pas une bonne idée car cela finira très probablement dans les journaux du serveur.
vous pouvez utiliser un schéma de réponse de défi. Disons que le client et le serveur connaissent tous deux un secret S. Alors le serveur peut être sûr que le client connaît le mot de passe (sans le donner) par:
- le serveur envoie un nombre aléatoire, R, au client.
- le Client renvoie H( R, S) vers le serveur (où H est une fonction de hachage cryptographique, comme SHA-256) Le serveur
- calcule H (R,S) et le compare à la réponse du client. Si 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 apatride. Cela peut être géré en demandant au serveur de créer un secret, appelez-le Q, Que seul le serveur sait . Alors le protocole va comme ceci:
- Numéro R. Il envoie alors au client H (R,Q) (qui ne peut pas être falsifié par le client).
- le Client envoie R, H (R,Q), et calcule H(R, S) et renvoie tout cela au serveur (où H est une fonction de hachage cryptographique, comme SHA-256) Le serveur
- calcule H (R,S) et le compare à la réponse du client. Puis il faut R et calcule (encore) H (R, Q). Si les versions H(R,Q) et H(R,S) du client correspondent au nouveau calcul du serveur, le serveur considère que le client authentifier.
à noter, puisque H(R,Q) Ne peut pas être forgé par le client, H(R,Q) agit comme un cookie (et pourrait donc être implémenté réellement comme un cookie).
Un Autre Edit:
l'édition précédente du protocole est incorrecte car quiconque a observé H(R,Q) semble pouvoir le rejouer avec le bon hachage. Le serveur doit se rappeler quels R ne sont plus frais. Je suis CW avec cette répondez pour que vous puissiez régler ça et trouver quelque chose de bien.
si votre hébergeur le permet, ou si vous avez besoin de traiter des données sensibles, utilisez HTTPS, period. (C'est souvent exigé par la loi afaik).
Sinon si vous voulez faire quelque chose sur HTTP. Je voudrais faire quelque chose comme cela.
- Le serveur intègre sa clé publique dans la page de connexion.
- le client remplit le formulaire d'ouverture de session et clique sur soumettre.
- une requête AJAX obtient le courant timestamp à partir du serveur.
- script côté Client concaténate les lettres de créance, l'horodatage et un sel (hachés à partir de données analogiques par exemple. les mouvements de la souris, les principaux événements de presse), chiffre à l'aide de la clé publique.
- soumet le hachage résultant.
- le serveur déchiffre le hachage
- vérifie si l'horodatage est assez récent (permet une fenêtre de 5-10 secondes seulement). Rejette le login si l'horodatage est trop ancien.
- stocke le hash pendant 20 secondes. Rejette le même hachage pour la connexion pendant cet intervalle.
- Authentifie l'utilisateur.
ainsi 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 la réutilisation d'un jeton de session volé un peu plus difficile.
- le le serveur définit un cookie de session supplémentaire qui contient une chaîne aléatoire.
- le navigateur renvoie ce cookie sur la requête suivante.
- le serveur vérifie la valeur du cookie, s'il est différent, il détruit la session, sinon tout va bien.
- le serveur réinitialise le cookie avec un texte différent.
donc si le token de session a été volé, et qu'une demande est envoyée par quelqu'un d'autre, alors sur l'utilisateur d'origine de la demande suivante, la session sera détruite. Donc si l'utilisateur parcourt activement le site, en cliquant souvent sur les liens, alors le voleur n'ira pas loin avec le jeton volé. Ce schéma peut être enrichi en exigeant une autre authentification pour les opérations sensibles (comme la suppression de Compte).
à propos de l'implémentation: RSA est probablement l'algorithme le plus connu, mais il est assez lent pour les longues clés. Je ne sais pas à quelle vitesse une implémentation de PHP ou Javascript serait être. Mais il y a probablement des algorithmes plus rapides.
j'utiliserais un système D'échange de clés Diffie-Hellman côté serveur et côté client avec AJAX ou multiple form submits(je recommande le premier), bien que je ne vois aucune bonne implémentation de celui-ci sur internet. Rappelez-vous qu'une bibliothèque JS peut toujours être corrompue ou changée par MITM. Le stockage Local peut être utilisé pour aider à combattre cela, dans une certaine mesure.
vous pouvez utiliser SRP pour utiliser des mots de passe sécurisés sur un canal non sécurisé. L'avantage est que même si un attaquant renifle le trafic, ou compromet le serveur, il ne peut pas utiliser les mots de passe sur un autre serveur. https://github.com/alax/jsrp est une bibliothèque javascript qui prend en charge les mots de passe sécurisés par HTTP dans le navigateur, ou Côté Serveur (via un noeud).
HTTPS est si puissant parce qu'il utilise la cryptographie asymétrique. Ce type de cryptographie permet non seulement de créer un tunnel chiffré mais vous pouvez vérifier que vous parlez à la bonne personne, et pas un hacker.
voici le code source Java qui utilise le chiffre asymétrique RSA (utilisé par PGP) pour communiquer: http://www.hushmail.com/services/downloads /
vous pouvez utiliser ssl pour votre hôte Il ya un projet gratuit pour ssl comme letsencrypt https://letsencrypt.org/