Rappel du contexte :Supposons qu'on utilise une formule proche :
Un client veut s'authentifier auprès d'un authenficateur (ici le serveur HTTP); il ne veut pas transmettre le mot de passe au serveur (même pas dans un tunnel chiffré).
Revenons sur la formule :
h = SHA-1(SHA-1(login || pw) || sid)
Je constate avec plaisir que le formulaire de connexion à lafibre.info est protégé contre l'écoute passive indépendamment de la sécurisation du transport :Question suivante :
Lors du login, les données sont :
user=corrector&passwrd=&cookieneverexp=on&hash_passwrd=d0e8581e75baad853b310e2fde3fbb86bcc4d754
en effet le formulaire est [1] :
<form action="https://lafibre.info/login2/" name="frmLogin" id="frmLogin" method="post" accept-charset="UTF-8" onsubmit="hashLoginPassword(this, 'd3de1bd9345835ceb39bc81fb4c06c27');">
la fonction hashLoginPassword(doForm, cur_session_id) (https://lafibre.info/Themes/default/scripts/script.js?fin20) qui contient notamment :
doForm.hash_passwrd.value = hex_sha1(hex_sha1(doForm.user.value.php_to8bit().php_strtolower() + doForm.passwrd.value.php_to8bit()) + cur_session_id);
Avec les explications ici, je comprends mieux pourquoi les donnés ne sont pas toutes sur le même serveur et pourquoi en cas d'attaque comme celle qu'a eu ubisoft, les données bancaires et autres ne sont pas impactés alors que les loging oui.Le coup de "on a été piraté, mais rien d'important n'a été atteint", j'ai comme du mal à y croire...
donc au lieu d'envoyer le mot de passe, le script envoie :On remarque qu'il y a là une fonction non injective : la concaténation de (login = toto, password = tata) donnera le même résultat qu'avec (login = totota, password = ta).hash = SHA-1(SHA-1(lower (login) || password) || sid)
Pensez-vous que cela peut poser problème?
Pourquoi?
Est-ce que l'usage de fonction non injective comme entrée d'une hachage cryptographique peut poser problème en général?
Non.Mais le contenu peut être intercepté et modifié, ou bien le POST peut être refait avec un autre user...
Car le nom d'utilisateur est transmis en clair dans le paramètre POST user, ainsi il n'y a pas de confusion possible pour le serveur.
2) il ne puisse pas usurper l'identité d'un utilisateur : pour ça, il faut donc que la base ne contienne pas les données qui permettent de s'authentifier auprès du serveur
Plusieurs commentaires rapides :Tout à fait.
- L'idée du poivre est d'être archi-protégé, il n'apparaît jamais en BDD (donc il n'est pas attaquable via SQL, ni via une sauvegarde de la BDD), il est dans un fichier spécial auquel seul le processus d'authentification accède, si n'importe quel client peut le récupérer ça n'apporte plus rien, autant le virer, le sel suffit bien.
- Comme fonction lente, bcrypt est vieux, scrypt est plus à la mode.Je note :)
SRP Protocol Design.Merci pour cette solution, qui permet à la fois :
...
Merci pour cette solution, qui permet à la fois :Oui, et aussi à l'utilisateur de vérifier l'identité d'un serveur TLS sans passer par un tiers de confiance, en initialisant la session avec la clé générée (TLS en mode PSK, sans certificat).
- De protéger la confidentialité du mot de passe, durant la phase d'authentification
- Qu'une compromission de la BDD utilisateurs ne permette pas à un attaquant de s'identifier en tant qu'un utilisateur
En revanche, il faut avouer qu'on monte tout de suite d'un cran en terme de complexité algorithmique, de complexité des échanges (nombreux allers retours clients <-> serveurs), et de complexité de mise en œuvre.Oui, la sécurité est rarement gratuite : quand le coût n'est pas la difficulté pour l'utilisateur, c'est en complexité d'implèmentation.
J'ai lu que la bonne pratique, pour le stockage d'informations d'authentification utilisateur sur un serveur, était de stocker en base de donnée, pour chaque utilisateur les éléments suivants :L'idée du poivre est de protéger au maximum l'accès au vérificateurs : seul le serveur qui a accès au poivre par un mécanisme hyper sécurisé peut faire les calculs de vérification des mdp. Ainsi même un pirate ayant accès à la table (SQL ou simple fichier texte) des utilisateurs ne peut rien en faire, il ne peut même pas tenter d'attaque par dictionnaire hors ligne.salt étant choisi aléatoirement, différent pour chaque utilisateur
- login
- hash = bcrypt (pepper || password || salt)
- salt
pepper étant codé en dur quelque part (idéalement, offusqué).
Merci pour ta réponseTout à fait.En terme de subtilité, parce que la cryptographie est un domaine pas du tout évident plein de pièges, surtout la crypto asymétrique et le choix de nombres premiers.
Je note pour les conseils de mise en place ;)
Je note :)
Merci pour cette solution, qui permet à la fois :En revanche, il faut avouer qu'on monte tout de suite d'un cran en terme de complexité algorithmique, de complexité des échanges (nombreux allers retours clients <-> serveurs), et de complexité de mise en œuvre.
- De protéger la confidentialité du mot de passe, durant la phase d'authentification
- Qu'une compromission de la BDD utilisateurs ne permette pas à un attaquant de s'identifier en tant qu'un utilisateur
Les caractéristiques souhaitables d'un protocole de vérification de mdp sont donc :On voit facilement que cela n'est pas faisable avec de la crypto symétrique uniquement.
- l'écoute passive ne révèle pas un vérificateur de mdp
Procéder autrement (ex : que le serveur envoie pepper et salt au client, pour que celui-ci calcule bcrypt (pepper || password || salt))Envoyer au client le poivre est hors de question. Admettons donc qu'il n'y a pas de poivre.
Un nonce (nounce) est un nombre qui n'est généré qu'une seule fois, dans l'Histoire. C'est un grand nombre aléatoire tel que la probabilité de le générer plusieurs fois est négligeable.Je reviens sur les nonces : il faut impérativement qu'ils n'y ai jamais de répétition, et qu'ils soient imprévisibles; pour ça il faut un générateur de nombres pseudo aléatoire de qualité cryptographique.
On fait des calculs avec cette valeur; le résultat de calcul a forcèment été produit après que le nonce ait été émis, et est lié à ce nonce : le nonce agit comme un identifiant de session.
Les caractéristiques souhaitables d'un protocole de vérification de mdp sont donc :
- aucun mdp ne circule en clair
- l'écoute passive ne révèle pas un vérificateur de mdp
- une attaque réseau active (MITM) ne révèle pas un vérificateur de mdp
- le serveur ne stocke pas les mdp en clair (ou équivalent clair)
- le serveur n'obtient pas le mdp en clair lors de l'exécution du protocole
- le serveur ne stocke pas un authentifiant
- le serveur n'obtient pas un authentifiant lors de l'exécution du protocole
- l'exécution du vérificateur est lente
- le protocole crée une session sécurisée
- le serveur ne peut pas être forcé faire des calculs ridiculement lourds (pour éviter le DoS)
lafibre est en HTTPS, donc je ne vois pas de quoi tu parles.
Les caractéristiques souhaitables d'un protocole de vérification de mdp sont donc :
(clear-pw) aucun mdp ne circule en clair
(pass-ver) l'écoute passive ne révèle pas un vérificateur de mdp
(mitm-ver) une attaque réseau active (MITM) ne révèle pas un vérificateur de mdp
(stor-pw) le serveur ne stocke pas les mdp en clair (ou équivalent clair)
(prot-pw) le serveur n'obtient pas le mdp en clair lors de l'exécution du protocole
(stor-auth) le serveur ne stocke pas un authentifiant
(prot-auth) le serveur n'obtient pas un authentifiant lors de l'exécution du protocole
(slow-verif) l'exécution du vérificateur est lente
(sec-session) le protocole crée une session sécurisée
(no-dos) le serveur ne peut pas être forcé faire des calculs ridiculement lourds (pour éviter le DoS)
La session sécurisée empêche une attaque active une fois que l'authentification a eu lieu : les requêtes sont liées à l'authentification par mdp, si elles sont modifiées elles ne seront plus considérées comme authentifiées.
Si j'ai bien compris le mécanisme d'authentification en place sur lafibre.info (et que celui-ci n'a pas changé depuis le premier post de ce topic) :Si tu parles de ce mécanisme au dessus de HTTP, alors non, il ne fournit pas tout ça.
- celui-ci possède les caractéristiques (clear-pw), (pass-ver), (mitm-ver), (stor-pw), (prot-pw), (sec-session) et (no-dos).
- en revanche, celui-ci ne possède pas les caractéristiques (stor-auth), (prot-auth) et (slow-verif).Exact.
Si j'ai bien compris le mécanisme d'authentification en place sur lafibre.infoMais fondamentalement cette question n'a pas de sens, parce que le mécanisme dont tu espères qu'il n'a pas changé n'est qu'une page HTML.
(et que celui-ci n'a pas changé depuis le premier post de ce topic) :Voilà, tu espères que l'implèmentation n'a pas changé.
(pass-ver) non donc (mitm-ver) sans objetJe ne vois pas le "vérificateur de mot de passe" transiter en clair dans les échanges :
(sec-session) nonJe faisais allusion au fait que nous sommes en HTTPS, mais effectivement, ce n'est pas le mécanisme d'authentification qui assure la session sécurisée. Donc c'est non ... mais pas forcèment gênant ici.
Donc le mécanisme affiche un formulaire HTML sur une page, donc rien n'indique à l'utilisateur comment ces données seront traitées.Non, mais nous venons de voir plus haut, que si le mécanisme côté client est ce qu'il est (le client reçoit "sid" et retourne "hash = SHA-1(SHA-1(lower (login) || password) || sid)", alors c'est que "SHA-1(lower (login) || password" est stocké côté serveur. D'où mes remarques sur les propriétés (stor-auth) et (prot-auth) à priori non couvertes.
Le vérificateur est une donnée qui permet de tester si un mdp est correct.J'aurais dû écrire un vérificateur est une fonction de l'ensemble de mdp autorisés vers les booléens indiquant si un pp (password potentiel) est correct.
Je ne vois pas le "vérificateur de mot de passe" transiter en clair dans les échanges :En capturant la connexion on peut récupérer :
- Le serveur envoie "sid" aléatoire
- Le client retourne hash = SHA-1(SHA-1(lower (login) || password) || sid)
- Le serveur récalcule hash = SHA-1(hpw || sid), et compare le résultat
La connaissance d'un vérificateur est donc suffisante pour effectuer une attaque par dictionnaire. (Le serveur doit stocker au moins les vérificateurs et pourrait tenter une attaque par dictionnaire.)En connaissant login et sid, je peux calculer SHA-1(SHA-1(lower (login) || pp) || sid) pour tout pp (password potentiel).