web-dev-qa-db-fra.com

Comment sécuriser les mots de passe via HTTP?

Disons 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 toute personne qui peut voir le trafic via cette connexion verrait le mot de passe en texte clair.

Ainsi, je pourrais le hacher côté client et laisser le serveur le comparer sans le hacher car il est déjà haché (ou le serveur pourrait même doubler le hachage, mais aucune différence dans cette situation). Mais là encore, toute personne qui peut voir le trafic verra le mot de passe haché, puis enverra le mot de passe haché au serveur et le serveur l'acceptera.

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

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

27
FireCubez

Tu ne peux pas.

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

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 cryptographie à clé publique. Vous pouvez bien sûr lancer 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 la cryptographie à clé secrète, comme Kerberos.

112
tim

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 envoyez au client, ou simplement injecter son 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 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 tags SRI.

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

45
AndrolGenhald

Bien que je convienne que vous devez utiliser HTTPS, vous pouvez le rendre encore plus sécurisé en utilisant le mécanisme d'authentification de réponse au défi salé (SCRAM, voir RFC 5802 ) pour l'échange d'authentification réel.

Ce n'est pas trivial à implémenter, mais l'essentiel est que, plutôt que d'envoyer le mot de passe au serveur, vous envoyez au serveur la preuve que vous connaissez le mot de passe. Étant donné que dériver 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 l'envoi du hachage lui-même).

Cela a 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 du 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 TLS 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 sur la base de l'échange. Cela dit, vous devez toujours utiliser HTTPS, car la défense en profondeur est meilleure.

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

25
Melanie

Vous devez certainement 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 allez finalement finir par implémenter un sous-ensemble de la fonctionnalité TLS. Il existe 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 de mettre en œuvre le système avec un langage qui n'offre pas de nombreuses 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 vous fier à cette implémentation qui résiste aux attaques temporelles, 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 comprend les composants de confiance les plus simples, bien compris et qui nécessitent que vous écriviez le moins de code critique pour la sécurité. Pour citer Andrew Tannenbaum:

Un nombre important de problèmes (dans la sécurité des applications) sont causés par des logiciels bogués, ce qui se produit 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.

7
Polynomial

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

Si vous envisagez d'essayer cela, vous pouvez tout aussi bien faire le plein kilomètre et utiliser HTTPS. Puisque vous ne semblez pas être un expert, le "chiffrement de votre propre" chiffrement aura sans aucun doute des erreurs de mise en œuvre qui le rendront peu sûr.

6
Brian Williams

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 authentification d'accès Digest :

REMARQUE: Le serveur conserve un HMAC du mot de passe et la clé correspondante ( Résumé );

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

Cela vous protège contre la relecture.

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

Remarque: HMAC peut être remplacé par PBKDF2.

2
Pierre del Perugia

Il existe en fait un moyen d'authentifier un utilisateur via une connexion non sécurisée: protocole Secure Remote Password (SRP) . 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 l'identité du client ultérieurement, que l'authentification ait réussi ou non. De plus, 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 chiffrement symétrique et/ou les HMAC.

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

  1. L'utilisateur doit s'être enregistré de manière sécurisée, car le processus d'enregistrement nécessite la transmission de matériel équivalent à un 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 fiable (c'est-à-dire qu'il n'exposera pas votre mot de passe à ce serveur, et vous pourrez 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 fiable (il pourrait envoyer une page qui capture toutes vos frappes et l'envoie quelque part).
  3. Bien qu'une 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 devrait être chargé à partir d'un serveur, et un attaquant pourrait altérer ce code pour voler la clé symétrique et apporter des modifications à la demandes 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 vous avez également un autre moyen sécurisé d'enregistrer les utilisateurs, SRP ne convient pas pour 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 usurpant le DNS) peut injecter du 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 toute clé générée et altérer toutes les demandes que vous envoyez ou les réponses que vous recevez à votre insu.

2
CBHacking

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

Malheureusement, il existe de nombreux problèmes avec HTTP-digest et le plus flagrant d'entre eux est que le serveur doit avoir le mot de passe en texte 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é des mots de passe sur le serveur pendant son utilisation. 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 avec le futur.

2

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 tout serveur à implémenter, est-ce à usage programmatique ou humain? Si vous êtes à usage humain, envisagez-vous l'authentification de base ou basée sur un formulaire? Et vos utilisations sont-elles capables d'appliquer un peu de logique, par exemple. pas pour joe public à utiliser. Faut-il protéger autre chose, ou simplement le mot de passe lui-même?

Si oui, vous pourrez peut-être regarder:

  • Utilisez un clavier/générateur de mot de passe unique (les fobs RSA ne sont pas bon marché, et si vous avez ce genre d'argent à dépenser, vous pouvez vous permettre TLS)
  • Un autre auth à 2 facteurs comme SMS (pas sans ses propres problèmes).
  • Un mécanisme de défi/réponse simple pour brouiller le mot de passe, par exemple la page affiche deux chiffres dessus dans le texte (non étiqueté de manière flagrante non plus), l'utilisateur doit démarrer le mot de passe avec un calcul simple tel que la différence entre les deux chiffres ajoutés à chaque chiffre d'un code PIN, peut-être avec des éléments aléatoires avant et/ou après, par exemple 98634572dkkgdld. La modification des numéros de défi devrait arrêter de rejouer les attaques qui ne sont pas essayées instantanément, mais si un attaquant peut capturer suffisamment de tentatives, il pourra peut-être le résoudre. Vous ne pouvez pas mettre de logique d'obscurcissement dans un script orienté utilisateur non plus 'cos qui 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 systèmes d'obscurcissement alambiqués n'ont vraiment plus de raison d'exister.

1
Richard N