Sommaire
Bonjour à tous,
Je vous propose un enième article sur un sujet bien connu : comment sécuriser des mots de passe dans une base de données. Et au passage, comment éviter de se taper la honte si votre BDD est leakée.
Après une longue réflexion, j'ai décidé de présenter ce journal sous forme de niveaux. Deux négatifs (-2 et -1) qui correspondent à des solutions (trop) souvent mises en place mais pas sécurisées du tout.
Puis, un niveau 0 qui devrait être la norme, et un niveau 1 pour les grosses BDD qui recèlent des millions d'informations critiques.
Préambule
Dans ce journal, il est question de fonctions de hachage. Elles permettent de convertir un message de taille arbitraire en une empreinte de taille fixe qui semble aléatoire. Exemple :
SHA1('Mon Super Message De La Mort Qui Tue') = 26e5f8bbf9e0e74a862c292f1eb181dfedc06261
Une telle fonction est qualifiée de fonction à sens unique, puisque le but est de rendre (calculatoirement) impossible la récupération du message original à partir d'une empreinte.
La seconde propriété d'une fonction de hachage, c'est qu'il doit être infaisable pour un attaquant de trouver deux messages différents qui donnent la même empreinte - on parle alors de collision.
Parmi les plus connues, on notera MD5, SHA1, SHA2 et SHA3.
Niveau -2 : MD5($pwd)
Une solution que vous avez tous du rencontrer une fois dans votre vie, c'est ça :
<?php
$query = mysql_query('select * from account where login = '.$login.' and pwd = MD5('.$password.')');
?>
Sans parler du fait que MD5 est une fonction de hash obsolète et cassée, c'est surtout la méthode ici qui n'est pas sécurisée.
Car croyez-moi, même avec un SHA2-256 ou même un SHA-3, je vous pète 95% de vos mots de passe en moins d'une journée.
Pour cela, rien de plus simple : je récupère une Rainbow Table, et je la fais correspondre avec votre base de données. Une Rainbow Table, c'est une table précalculée de valeurs en clair et leurs hash associés :
Niveau -1 : SHA1($salt + $pwd)
Avec cette méthode, on sent que la personne qui a essayé de sécuriser ses mots de passe y a mis un peu plus de volonté en rajoutant un sel, c'est-à-dire une valeur constante qu'il concatène aux mots de passe avant de les hasher.
Ca a pour avantage d'invalider les Rainbow Table existantes, mais ce n'est malheureusement pas suffisant.
Pour casser ça, on part d'un utilisateur dont on connaît déjà le mot de passe en clair (un ami ou nous-même qui avons crée un compte sur la plateforme).
On lance alors une attaque brute-force pour déterminer le sel global. Ca peut prendre jusqu'à une semaine selon la force du sel.
Une fois le sel trouvé, on retrouve à nouveaux 95% des mots de passe en calculant une nouvelle Rainbow Table basée sur ce sel.
A noter aussi que si l'attaquant a un accès plus important que la BDD (code source de la plateforme), il peut directement trouver le fichier dans lequel est stocké le sel.. Dans ce cas, on retrouve le même niveau de sécurité qu'en -2.
Niveau 0 : bcrypt($perUserSalt, $pwd)
Là, on arrive enfin à quelque chose de convenable. Par rapport au niveau -1, deux choses changent :
- Au lieu d'utiliser une fonction de hash classique, on utilise des procédures dédiée aux mots de passe. bcrypt (basé sur l'algorithme de chiffrement Blowfish) et scrypt sont les deux plus connues, et ont comme avantage d'être lentes à calculer. Pour un attaquant, ça rend le procédé de brute-force beaucoup plus long. Pour la plateforme, la perte en performances est négligeable (un utilisateur se connecte une fois et point barre).
- Le sel global devient un sel généré aléatoirement pour chaque utilisateur. Ainsi, même si l'on retrouve le mot de passe d'un utilisateur - ce qui peut prendre plusieurs semaines à cause de la lenteur de bcrypt/scrypt -, cela ne compromet pas ceux des autres.
Voici à quoi peut ressembler une BDD basée sur bcrypt :
On peut voir ici que le champ "password" contient plus que le hash des mots de passe. Il contient ces informations :
- $2a : Algorithme utilisé (en l'occurence Bcrypt avec un mot de passe UTF-8)
- $10 : niveau de difficulté choisi pour l'algorithme (parce que oui, c'est configurable selon la puissance de la plateforme)
- $NOLgNI4iSzHbxYj3/CNW3OAf9/dmuOOCMsF1oPNjhThyG6eaDnB0e : le sel (16 octets) et le hash (24 octets) codés en Base64 puis concaténés
Niveau 1 : AES(bcrypt($perUserSalt, $pwd), $secretKey)
Fiou, là c'est du haut de gamme ! De la haute voltige de la protection de mot de passe.
Pour les grosses plateformes remplies de millions d'informations utilisateurs, le top du top consiste à rajouter une couche de chiffrement sur le hash - avec AES par exemple -, associée à une clé constante.
Attention cependant, tout dépend de la sécurité du stockage de cette clé secrète. C'est pourquoi il est conseillé d'utiliser un HSM.
Un HSM, pour faire court, est un serveur cryptographique qui possède des protections physiques : Il "tilt" (effacement des données) si l'on tente de l'ouvrir ou de le déplacer, et ses composants électroniques sont coulés dans un mélange qui les rend physiquement inaccessibles.
Logiciellement, il agit comme une boîte noire de chiffrement/déchiffrement et autres primitives cryptographiques, requêtables par réseau.
Pour le coup, si vous avez une implémentation rigoureuse de ça, avec en plus l'utilisation d'un HSM, la probabilité qu'un attaquant arrive à ne casser ne serait-ce qu'un seul mot de passe est minime.
Et vous, vous utilisez quoi ? :>
# Niveau 0
Posté par coid . Évalué à 4. Dernière modification le 17 janvier 2014 à 12:48.
Je me posais justement des questions sur le niveau de sécurité à adopter pour un nouveau site, et j’ai plusieurs questions.
Qu’apporte le sel différent pour chaque utilisateur, dans la mesure où si le code est leaké, le pirate peut avoir accès à la méthode aussi bien qu’à un sel global ? Du coup, ça ne change rien, me semble-t-il. À moins qu’il soit plus facile de récupérer une BDD que le code ? Ce point me chiffonne.
Ensuite, sauf erreur de ma part, bcrypt ne protège vraiment bien que les mots de passe bien foutu. Avec une rainbow-table, 95 % des passes sont cassés pareillement.
Du coup, la différence entre le niveau -1 et le niveau 0 me paraît minime si le code a fuité, elle ne joue que pour 5 % des mots de passe, ceux bien conçus. Ça fait des ennuis pour pas grand-chose, à moins d’interdire des mots de passe faibles, ce qui est rédhibitoire pour beaucoup de gens.
(Ce n’est pas du troll, juste des questions, j’hésite sur les choix à faire.)
[^] # Re: Niveau 0
Posté par goeb . Évalué à 4.
Mais si tu veux casser un mot de passe salé, tu dois d'abord calculer ta rainbow table avec ce sel. Ça prend combien de temps de calculer une rainbow table ? Je pense que c'est long.
Donc le concept de rainbow table ne peut pas être utilisé avec les mots de passe salés unitairement (chaque mot-de-passe est salé avec un sel dédié).
[^] # Re: Niveau 0
Posté par Ely . Évalué à 3.
Calculer une rainbow table : pas longtemps avec une carte graphique. Une Radeon 7970 est capable de faire 600 millions de SHA2 à la seconde. Sachant qu'une rainbow table ne contient que des mots de passe "populaires", je pense que ta table est très vite générée.
[^] # Re: Niveau 0
Posté par Ely . Évalué à 6.
EDIT : Sauf si bien sûr l'algorithme est bcrypt, là calculer une rainbow table peut prendre lonnngttemmppss.
[^] # Re: Niveau 0
Posté par flavien75 . Évalué à 10. Dernière modification le 17 janvier 2014 à 13:01.
Dans ce cas l'attaquant doit générer une rainbow-table par mot de passe.
Personnellement, plutôt que de générer le sel aléatoirement et devoir le stocker, je concatène une constante, le nom d'utilisateur et le mot de passe
Comme il est dit dans l'article, il faut absolument éviter que 2 mots de passe identiques donnent le même résultat.
Sinon il faudrait aussi parler du niveau -3: on stocke les mots de passe cryptés par une constante planquée de le code (rigolez pas, je suis sûr que ça existe)
Les vrais naviguent en -42
[^] # Re: Niveau 0
Posté par patapon . Évalué à 3.
Déjà vu… Et encore, "planquée", le mot est fort…
[^] # Re: Niveau 0
Posté par Moonz . Évalué à 8.
Et les mots de passe en clair c'est le niveau combien ?
(oui, j’en ai vu dans un projet codé en 2013)
[^] # Re: Niveau 0
Posté par flavien75 . Évalué à 6.
ça doit être le niveau -42
Les vrais naviguent en -42
[^] # Re: Niveau 0
Posté par Patrick Nicolas . Évalué à 2.
La solution est de générer aléatoirement le sel pour chaque utilisateur au moment de la création du compte (ou réinitialisation du mot de passe). Dans le journal on voit que la BDD contient sel et hash du mot de passe pour chaque utilisateur.
Je dirais aussi que les 2 améliorations entre -1 et 0 sont indépendantes, bcrypt améliore la sécurité du hash en rendant les attaques par force brute plus difficiles, le sel par utilisateur invalide les hash précalculés.
[^] # Re: Niveau 0
Posté par zebul0n (site web personnel) . Évalué à 5.
Ajouter un module comme pgcrypto, c'est pas de l'ordre de l'insurmontable …
[^] # Re: Niveau 0
Posté par Ely . Évalué à 6.
Que veux-tu qu'il découvre dans ta "méthode" ? La force de la cryptographie moderne, c'est que tous les algorithmes (AES, SHA-X, bcrypt, RSA…) sont open-source, et pourtant on n'arrive pas à les casser.
Le sel différent pour chaque utilisateur fait qu'il faut recalculer une rainbow table à chaque fois. Car même si deux utilisateurs ont le même mot de passe, le haché sera différent à cause du sel différent justement.
Avec un algorithme lent comme bcrypt, recalculer une rainbow table peut prendre des plombes.
[^] # Re: Niveau 0
Posté par coid . Évalué à 1.
La méthode de salage individuel.
OK, je comprends la théorie, mais dans la pratique je demeure un peu sceptique sur l’intérêt de la chose. Alourdir de 100 fois, 1000 fois, voire bien plus encore chaque connexion à son compte me semble plutôt coûteux au final, tout ça juste pour ralentir l’éventuel décodage des mots de passe merdiques, sachant que les mots de passe corrects ne sont pas vulnérables avec la méthode des rainbow-tables.
Ça donne matière à réfléchir.
[^] # Re: Niveau 0
Posté par KiKouN . Évalué à 1.
Si on élimine les mots de passe présentes dans les rainbow tables existantes. Les utilisateurs vont devoir retrouvé un nouveau mot de passe, mais ils vont le faire comme des moutons ( code sur une étiquette ou numéro de série, mot de passe à partir de la dernière chanteuse à la mode et le nombre de fois qu'elle va au petit coin par jour et bien d'autre ).
Refaire une rainbow table n'est alors pas difficile. On peut faire un site bidon juste pour récupérer ces nouveaux mot de passe ( en plus, on parait sécure car on interdit les mots de passe présents dans les autres rainbow tables ), keyscan, suite à un autre crackage de base de données ou analyse des rêves du chien de la voisine qui vous a entendu taper votre mot de passe pendant son petit tour matinal.
Bref, n'importe quel mot de passe est susceptible de se retrouver dans une rainbow table. Je rappel aussi que le but est d'avoir une premier accès à un système pour soit utiliser ce compte soit avoir un éventail plus grand de faille permettant d'obtenir un prompt root ou autre chose, retrouver un seul mot de passe parmis les milliers d'utilisateur est suffisant pour cela, et cette accès risque de rendre encore plus probable que ton mot de passe bien costaux se retrouve dans une liste et tu te retrouvera le maillon faible de la prochain cible.
# Niveau -3
Posté par Zenitram (site web personnel) . Évalué à 10.
Il manque un niveau :
Niveau -3 : $pwd
(j'ai encore vu en 2014 des sites te renvoyer ton mot de passe par mail quand tu dis avoir oublié ton mot de passe)
[^] # Re: Niveau -3
Posté par devnewton 🍺 (site web personnel) . Évalué à 10.
J'ajoute le niveau -4:
Le post ci-dessus est une grosse connerie, ne le lisez pas sérieusement.
[^] # Re: Niveau -3
Posté par Ely . Évalué à 10.
En effet, j'aurais pu rajouter ce niveau.
Par contre, attention aux préjugés, un site qui est capable de te renvoyer ton mot de passe en clair peut très bien incorporer un mécanisme de protection des mots de passe tout à fait potable.
Je prends l'exemple suivant : $passwordInDatabase = AES($password, DerivateKey($constantSecretKey, $perUserSalt))
En fait, le site ne procède qu'à un chiffrement du mot de passe, pas de hash. Si ceci est bien implémenté, c'est-à-dire que la clé secrète constante est protégée dans un élément sécurisé (ex. HSM) et que le sel unique par utilisateur est généré de façon cryptographiquement secure, c'est une technique qu'on ne cassera pas.
Et évidemment, avantage (ou pas), c'est que le site est capable de déchiffrer le mot de passe si besoin est.
La seule attaque contre ça, c'est de prendre le contrôle totale de la plateforme, et d'envoyer les mots de passe un par un au HSM pour les déchiffrer. Faut déjà y aller pour un attaquant.
[^] # Re: Niveau -3
Posté par paco81 . Évalué à 6. Dernière modification le 17 janvier 2014 à 14:00.
Et en pratique, c'est souvent le cas ?
Parce qu'on peut se dire que ce sera beaucoup plus facile pour ledit site de te renvoyer un nouveau mot de passe par mail plutôt que de vouloir absolument être capable de déchiffrer ton mot de passe, quitte à s'équiper d'un HSM (ce qui ne doit pas être du matériel tout à fait anodin).
Et bravo pour ton journal, très instructif.
[^] # Re: Niveau -3
Posté par Ely . Évalué à 3.
Alors là, je ne saurais te répondre.
Un HSM, c'est peu probable. C'est du matériel qui coûte hyper cher (genre 15.000€ l'entrée de gamme).
Par contre, un SSM (Software Security Module), pourquoi pas. C'est en gros un HSM sans la partie "protection physique". Un bête serveur sur lequel tu as mis des règles iptables, des droits d'accès aux fichiers les plus stricts possibles, et qui fait tourner un démon réseau de chiffrement/déchiffrement.
[^] # Re: Niveau -3
Posté par oinkoink_daotter . Évalué à 3.
Non, pas nécessairement, ça dépend de beaucoup de paramètres. Par exemple un YubiHSM ça coute 500$ et niveau sécu, apparemment, c'est pas mal. Par contre, clairement, tu ne chifferas pas un 1Gb/s. Un TPM, aussi, c'est très bien. Mais la, c'est vraiment très très lent.
[^] # Re: Niveau -3
Posté par Ely . Évalué à 2.
Ouaip, je pensais plus aux HSM type serveur plutôt que clé usb. Au boulot on a des Thalès PayShield, et ça douille niveau prix..!
[^] # Re: Niveau -3
Posté par oinkoink_daotter . Évalué à 4.
Ah bah vi, c'est du serious bizness !
[^] # Re: Niveau -3
Posté par zebul0n (site web personnel) . Évalué à 8.
Que dire de plus ?
[^] # Re: Niveau -3
Posté par bobo38 . Évalué à 3.
bien déterré ;)
[^] # Re: Niveau -3
Posté par Maxime (site web personnel) . Évalué à 3.
C'est par exemple le cas de Sarenza… Qui te mail ton mot de passe en clair.
# Dernier angle d'attaque
Posté par lolop (site web personnel) . Évalué à 3.
L'interface chaise-clavier. Mais c'est un autre problème.
Votez les 30 juin et 7 juillet, en connaissance de cause. http://www.pointal.net/VotesDeputesRN
[^] # Re: Dernier angle d'attaque
Posté par stopspam . Évalué à 10.
[^] # Re: Dernier angle d'attaque
Posté par bobo38 . Évalué à -10.
Da Linux French Page ? gné ?
(je dois être stupide puisque je ne comprends pas)
[^] # Re: Dernier angle d'attaque
Posté par Marotte ⛧ . Évalué à 7.
Je ne sais pas à qui tu réponds, tu as dû répondre au mauvais endroit.
« Da Linux French Page » c'est si je ne m'abuse l'ancien nom de LinuxFR, ou un nom alternatif… À confirmer.
[^] # Re: Dernier angle d'attaque
Posté par dave_null (site web personnel) . Évalué à 3. Dernière modification le 17 janvier 2014 à 20:25.
Cadeau : http://www.lirmm.fr/~gambette/xkcd/index.php?id=538
On doit te le dire souvent, mais ne pas lire l'anglais est un handicap dans le monde de l'informatique.
[^] # Re: Dernier angle d'attaque
Posté par Marotte ⛧ . Évalué à 0. Dernière modification le 18 janvier 2014 à 00:13.
Moi je comprends strictement rien à cette discussion. Avoir la comprenette difficile c'est aussi un handicap, dans l'informatique comme ailleurs ! :)
Tu lui ressors un lien vers le xkcd sur l'écart entre l'imagination du crypto-nerd et la réalité de l'association de malfaiteurs (posté juste avant…), pourquoi ?
L'anglais est une langue magnifique, brillante de simplicité comparé au français ou au polonais. Mais là je ne saisi pas. bobo38 s'interroge visiblement sur « Da Linux French Page », ce qui ne présume en rien de sa faculté de compréhension de la langue anglaise.
Est-ce que tu ne serais pas sous LSD par hasard ? Quel est ton mot de passe root ?
[^] # Re: Dernier angle d'attaque
Posté par dave_null (site web personnel) . Évalué à 2.
Hint: Il y a la traduction juste en dessous de l'image dans la page en lien.
[^] # Re: Dernier angle d'attaque
Posté par Marotte ⛧ . Évalué à 2.
Ha oui OK :) Bah je préfère la mienne de traduction pour le coup ;)
Sauf pour "got it" = "je m'en occupe", j'avoue que c'est mieux que simplement "OK".
[^] # Re: Dernier angle d'attaque
Posté par Kerro . Évalué à 5.
« got it » veut dire « j'ai compris » ou plutôt « j'ai pigé ».
[^] # Re: Dernier angle d'attaque
Posté par stopspam . Évalué à 1. Dernière modification le 18 janvier 2014 à 18:56.
Le crypto-nerd veut faire la même chose que le malfaiteur, pour moi ils sont tous les deux malfaiteurs sauf que l'un est incroyablement plus intelligent que l'autre (et je ne parle pas du nerd).
[^] # Re: Dernier angle d'attaque
Posté par ariasuni . Évalué à 5.
Qu'est-ce qu'il ne faut pas entendre…
L'anglais est très compliqué, à peu près à égalité avec le français (la prononciation de l'anglais rattrape la grammaire/conjugaison française). Les seules langues réellement simples sont les langues construites, comme l'espéranto.
Écrit en Bépo selon l’orthographe de 1990
[^] # Re: Dernier angle d'attaque
Posté par Marotte ⛧ . Évalué à 4.
Alors au cas où, je te traduis la bande dessinée.
Première vignette : Dans l'imagination d'une as de la cryptographie.
« Son portable est chiffré, construisons une grappe d'ordinateur à un million de dollar pour casser le chiffrement.
- Impossible c'est du RSA 4096 bits !
- Merde ! Notre plan diabolique est fichu ! »
Deuxième vignette : Ce qui se passerait dans la réalité.
« Son portable est chiffré, drogue-le et frappe le avec cette clé à molette à cinq dollar jusqu'à ce qu'il nous révèle son mot de passe.
- OK. »
Cette traduction vous a été proposé par « Da Marotte Institute for Lame Translations » (L'institut Marotte pour des traductions bancales) :)
# retrouver le salt ???
Posté par stopspam . Évalué à 3. Dernière modification le 17 janvier 2014 à 13:52.
Je ne suis pas spécialiste, j'essaie juste de comprendre plusieurs de tes affirmations :
Tu sors ça d'où ?? L'explication et une implémentation existante m'intéressent.
Tu n'as pas parlé de la longueur du salt ? les rainbows tables se basent sur des longueurs de caractères prédéfinies. Ne penses-tu pas que l'intérêt du salt est justement d'être suffisamment grand pour justement bloquer les attaques par rainbow table ? Si mon salt fait 100 char, tu le pètes aussi ?
[^] # Re: retrouver le salt ???
Posté par Ely . Évalué à 10. Dernière modification le 17 janvier 2014 à 13:59.
Je vais faire avec un exemple.
Mettons que tu aies un compte sur le site dont le mot de passe est "1234". La BDD est leakée, tu retrouves ton compte avec le mot de passe haché associé : c6c4940b323ff81c66e02a02e0281c370c535008
Premier réflexe, tu regardes la longueur du haché. En l'occurence, c'est 20 octets, ce qui laisse présumer que le site a utilisé SHA-1. Tu essaies donc naïvement :
Argl, pas le même résultat ! Tu lances alors une attaque brute-force, qui prendra plus ou moins de temps selon la longueur du sel :
et là, à un moment… bingo !
Le sel est donc "azerty".
Ensuite, tu recalcules toute une rainbow table en prenant en compte ce sel (ce qui n'est pas très long) :
etc etc.
Je suis d'accord avec toi que si le sel fait 100 caractères de long, ça sera beaucoup plus long à casser. Le vrai problème réside en fait dans ce que j'ai dit dans l'article :
EDIT : j'oubliais le plus important : avec un sel constant, deux utilisateurs qui ont le même mot de passe auront le même haché ! Et ça c'est grave.
[^] # Re: retrouver le salt ???
Posté par nud . Évalué à 6.
Si le préfixe/suffixe est suffisament court, tu peux aussi trouver directement le hash dans une rainbow table sans préfixe.
Avec un peu de bol, et vu que théoriquement plusieurs strings pourraient avoir le même hash mais que c'est hautement improbable voire impossible avec des strings de longueur raisonnable, le hash et le mot de passe associé dans la rainbow table seront équivalents à la concaténation du salt et du mot de passe.
[^] # Re: retrouver le salt ???
Posté par cluxter . Évalué à 1.
Merci pour cet exemple explicatif très clair.
Du coup, ne pourrait-on pas faire un sel qui serait basé sur le mot de passe ? Le but étant d'obtenir un sel unique par mot de passe.
En reprenant ton exemple :
J'ai un mot de passe '1234', mon login est 'obiwan'.
Je calcule un sel avec disons : SHA1("1234" & "obiwan")
Là j'obtiens comme sel : 6957a6c55c640f0543951578fadd4823a36495b2
Puis je calcule le hash du sel + mot de passe : SHA1("6957a6c55c640f0543951578fadd4823a36495b2" & "1234")
Ce qui donne comme résultat final qu'on stocke dans la BDD : 339690467416b7c7e7b966e8a598f3822e0338d0
Si maintenant je change le mot de passe, mon sel va également changer automatiquement.
Je serais donc tenté de dire qu'il me faudra générer une rainbow table à chaque fois que l'utilisateur change son mot de passe puisque le sel change avec le mot de passe.
Qu'en pensez-vous ?
[^] # Re: retrouver le salt ???
Posté par rakoo (site web personnel) . Évalué à 1.
Qu'au lieu de dépendre de deux paramètres, ce que tu stockes en DB ne dépend plus que d'un seul paramètre; c'est comme si tu n'utilisais pas de sel.
[^] # Re: retrouver le salt ???
Posté par Ely . Évalué à 1. Dernière modification le 03 février 2014 à 16:32.
Au contraire, la technique est "pas trop mal" et ça invalide les rainbow table "classiques".
Le problème, c'est qu'utiliser un login comme sel n'est pas une donnée suffisamment forte. Il existe probablement déjà des rainbow table calculées avec différents sels tirés de mots ordinaires. Or, il se peut très bien qu'un de ces mots soit "obiwan" par exemple.
Donc certes il faut une rainbow table par haché dans ta base, mais vu la sécurité de tes sels (caractères alpha-numériques), on peut estimer qu'elles existent déjà (genre si tu as des utilisateurs qui ont un login entre 2 et 5 lettres.. c'est mort pour eux).
Le mieux reste donc de générer un sel aléatoire et suffisament grand, et de le stocker dans la base. Au moins, pas de mauvaise surprise comme ça.
# niveau -0.5
Posté par Zylabon . Évalué à 4.
Je me pose une question peut être bête…
Est-ce que SHA1(random()%$n + $pwd) serait pertinent ? Ça affaiblit d'un facteur n vis à vis du brute force, mais les tables arc-en-ciels ne sont plus envisageable si chaque mot de passe peut être hashé aléatoirement. Non ?
Please do not feed the trolls
[^] # Re: niveau -0.5
Posté par nud . Évalué à 10.
Question con: comment tu fais pour vérifier ton mot de passe ? Il te faut stocker la valeur aléatoire que tu utilises d'une façon ou d'une autre, soit en l'ajoutant en clair au hash (comme crypt() et bcrypt()), soit en utilisant une valeur connue, dérivée de l'utilisateur (son username, son id multiplié par 1313, etc) sinon tu ne seras jamais en mesure de recalculer le même hash, car la valeur aléatoire sera différente à chaque fois.
[^] # Re: niveau -0.5
Posté par fabien . Évalué à 3.
j'en profite pour rebondir sur ce point :
C'est bien ce que j'avais cru comprendre,avec bcrypt le sel est donnée dans la base de données…
C'est plutot curieux comme technique, pour du niveau 0, je privilegirai plus une approche tel que :
SHA1(SHA1(username) + sel + SHA(password))
où on aurait donc SHA1(usname) qui serait le perUserSalt mais non communiqué.
[^] # Re: niveau -0.5
Posté par nud . Évalué à 10.
Si le sel n'est pas aléatoire, ça ne sert à rien.
Si le sel est aléatoire, tu dois l'avoir en clair, si tu le hashes tu ne le retrouveras jamais.
De toute façon, la première faille de sécurité est en fait de vouloir se prendre pour un expert en crypto:
[^] # Re: niveau -0.5
Posté par Ely . Évalué à 3.
Règle de base en cryptographie : ne jamais assumer qu'une information "non communiquée" ne sera jamais découverte. La cryptographie par obfuscation (on cache les algorithmes et les constantes) a toujours échoué à un moment ou un autre.
Le problème de prendre un nom d'utilisateur comme $perUserSalt, c'est que ce n'est pas une donnée cryptographiquement sécurisée. Par exemple, les octets qui le composent ne peuvent pas prendre toutes les valeurs possibles : seulement des caractères imprimables.
Le fait de limiter "l'aléatoire" du sel peut faciliter une attaque.
Il est donc préférable de générer un sel aléatoire qui sera plus fiable.
[^] # Re: niveau -0.5
Posté par cosmocat . Évalué à 4.
Pour moi, un sel doit avoir les même caractéristiques qu'un mot de passe : contenir des chiffres, des lettres en minuscules et majuscules, contenir des caractères autres et d'être d'une certaine taille ( en plus tu n'es pas contraint par la mémoire d'un utilisateur alors tu peux te lâcher!! 100 caractères si besoin…). Comme ça tu invalides TOTALEMENT les rainbow tables et il ne reste que le brute force pour l'attaquant.
[^] # Re: niveau -0.5
Posté par Ely . Évalué à 7.
Justement non. Un sel idéal, c'est un sel le plus aléatoire possible, et dont les octets peuvent prendre toutes les valeurs (0 -> 255). Pour faire ça sur un PC, on se base sur ce que l'on peut récupérer sur les différentes entrées et capteurs que l'ordinateur possède : tensions, températures, mouvements de la souris, frappes au clavier… On fait un mic-mac binaire de tout ça, et on obtient de l'aléatoire "cryptographiquement sécurisé".
Tu invalides aussi "totalement" les rainbow tables, mais en encore mieux qu'avec un sel qui ne contiendrait que des caractères imprimables (valeurs de 32 à 175 dans la table ascii).
[^] # Re: niveau -0.5
Posté par KiKouN . Évalué à 2.
Le sel ne peut invalider l'utilisation des rainbow table. Cela les rends juste plus difficilement exploitables.
Il ne faut pas oublier tout les cas. Si un attaquant a obtenu votre DB. Il aura votre sel qu'il soit par utilisateur ou global.
S'il a obtenu qu'un mot de passe salé et hashé, il pourra retrouver le sel. Dommage si le sel est global. Mais il aura un accés à un compte, il pourra déjà en faire quelques choses ( envoi spam, tester des failles ) qui réduira la qualité de service global.
[^] # Re: niveau -0.5
Posté par cosmocat . Évalué à 6.
Si tu permet à tes utilisateurs de changer son login (par exemple le login est en fait leur adresse mail), tout ta stratégie (en plus d'être déjà mauvaise) tombe encore plus à l'eau…
[^] # Re: niveau -0.5
Posté par fabien . Évalué à 2. Dernière modification le 20 janvier 2014 à 00:50.
J'aime pas vraiment l'idée d'avoir une adresse email en tant que login. Mais de toute maniere ce que j'ai écrit c'etait dans l'hypothese du "niveau 0", il y a donc des lacunes, oui cette "strategie" peut être qualifié de "vraiment mauvaise" ok. L'idée c'était histoire d'avoir quelque chose entre le niveau -1 et le niveau 0 entierement a base de SHA1. (même si ca se rapproche plus d'un 0 pour moi, question de gout, je me tompe sans doute)
Et sinon, merci a je sais plus qui pour le cours sur les "Règle de base en cryptographie", l'obfuscation et le tralala… Mais je n'ai jamais dit que cette strategie "niveau 0" (voir -0.5 comme dans le titre) se reposait sur une obfuscation. Mais simplement qu'a choisir je prefere ne pas donner le sel, c'est tout. c'est un petit "plus", partant de cette idée je trouvai original au niveau du concept de voir que dans la methode proposé (niv0), le sel est fourni dans la base quoi (voir note 1) alors, ok c'est cool on s'appuie (les yeux fermés) sur l'algo qui est tellement balez qu'on peut se permetre de donner des infos, bon ok. d'où l'idée d'avoir un selPerUser generé (une empreinte du username ou userId pour une meilleur perenité), bien sûr il y a des défauts comme justement relevé par cosmocat, je n'ai pas la pretention de faire du haut de gamme non plus, juste un truc simple et mieux que le niveau -1 proposé, qui lui n'a qu'un sel fixe et commun.
note 1 : Oui dans le cas d'un sel non public, je sais bien qu'il faut qu'il soit a priori dans le code, donc vulnerable aussi, comme la BDD. Et donc, que le hacker a de fortes chances d'y avoir accés aussi, j'ai lu tout ca, ok. mais n'empche je prefere ne pas avoir tout dans le même panier, ne serait-ce que pour les faibles petit 10% de chance où le hacker n'a que la bdd.
voilà.
[^] # Re: niveau -0.5
Posté par claudex . Évalué à 3.
En fait, c'est bien pratique sur les sites que je ne fréquente pas souvent parce que j'ai plus de login possible que d'adresse mail.
« Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche
[^] # Re: niveau -0.5
Posté par Krunch (site web personnel) . Évalué à 3.
Tu peux aussi dédier un domaine aux comptes avec un catchall. Genre identifiants.example.org. Et pour DLFP par exemple tu utiliserais linuxfr.org@identifiants.example.org.
Après, si tu es pauvre et que tu n'as pas la possibilité de mettre de catchall, tu peux toujours utiliser luser+linuxfr.org@example.org. Par contre ça va pas marcher avec les sites qui acceptent pas les "+" dans l'e-mail.
Avec tout ça, tu as un e-mail par compte et tu peux le retrouver assez facilement sur base du site que tu utilises.
pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.
[^] # Re: niveau -0.5
Posté par Zylabon . Évalué à 6.
En essayant tout les sels possible… c'est juste n fois plus long…
Please do not feed the trolls
[^] # Re: niveau -0.5
Posté par Snarky . Évalué à 2.
Ça a la même utilité que ça:
Totalement sécure, mais comment on fait si on doit vérifier le mot de passé saisi ?
:)
[^] # Re: niveau -0.5
Posté par Zylabon . Évalué à 4.
comme ça :
Please do not feed the trolls
[^] # Re: niveau -0.5
Posté par Krunch (site web personnel) . Évalué à 4.
Ce qui est sympa (pour l'attaquant) avec ce genre de truc c'est que pour chaque identifiant il y a plusieurs mots de passe possible.
pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.
[^] # Re: niveau -0.5
Posté par Zylabon . Évalué à 2.
Mon post initial :
Please do not feed the trolls
# crypt()
Posté par nud . Évalué à 8.
Quid de la fonction crypt() ? Cette fonction utilise un algorithme configurable (md5, blowfish, sha-256 ou sha-512) avec un salt de la même façon que l'explication de bcrypt(), la lenteur artificielle en moins (crypt() n'applique pas la fonction de hash plusieurs fois). Comme pour bcrypt, l'algorithme choisis influence la "force" du hash.
Il faut aussi mentionner que, tant pour crypt() que pour bcrypt(), le salt est intégré (en tant que préfixe) au hash final, après le numéro de l'algo de hashage utilisé. Donc, pour vérifier si un mot de passe est correct, il suffit de vérifier que (b)crypt(passwd, passwd) == hash.
Bref, si vous n'avez pas de bcrypt() disponible, utilisez crypt() plutôt qu'une solution "à la main"…
# SHA2($saltperuser, $stretching, $pwd)
Posté par Miguel Moquillon (site web personnel) . Évalué à 3.
C'est que j'utilise pour protéger les mots de passe d'accès à une application Web. Le sel et le stretching sont propres à chaque utilisateur et sont renouvelés à chaque changement de mots/phrases de passe.
Le SHA-2 ici utilisé est du SHA 512 et l'algorithme de cryptage avec le salt et stretching est celui en vigueur sous Unix.
Quant à l'AES (AES-256), je l'utilise plutôt pour chiffrer du contenu sensible et la clé utilisée elle-même chiffrée avec du CAST5 (CAST-128).
# AES est une mauvaise fonction de hashage !
Posté par Nicolas Boulay (site web personnel) . Évalué à -2.
Il ne faut pas utiliser AES comme ça. C'est juste une mauvaise fonction de hash, si la clef est unique sur la plateforme. J'imagine qu'avec un mauvais mot de passe, si le sel peut être trouvé, on peut retrouver la clef (le problème est d'utiliser une fonction symétrique). D'ailleurs, cela revient au même si vous utilisez un sel unique pour la plate forme, sauf que l'on ne peut pas faire d'opération inverse. En général, il ne faut jamais utiliser de fonction symétrique, si on veut simplement un hash. Il y a toujours moyen de l'utiliser "à l'envers" pour casser la protection.
Pour éviter le brute force à la hashcat, il faut utiliser des fonctions de hash chiante, il en existe quelques une. Le plus simple est de faire x fois sha256(), cela prends plus de temps, et cela augmente la durée de vie des mots de passe.
"La première sécurité est la liberté"
[^] # Re: AES est une mauvaise fonction de hashage !
Posté par Ely . Évalué à 6.
Attention, la majorité des choses que tu as dites sont fausses.
Il n'y a pas de mal à utiliser AES avec une clé constante pour toute la BDD si l'on chiffre un haché bien fait, comme dans le niveau 1 que j'ai décrit : AES(bcrypt($perUserSalt, $pwd), $secretKey)
Tu dis aussi "on peut retrouver la clef, parce qu'AES est symétrique" : et bien non. Même si tu connais un clair et son chiffré AES, il n'y a aucun moyen de retrouver la clé. Et heureusement d'ailleurs, sinon ça serait cassé depuis longtemps…
Quant à la méthode que tu décris qui fait x fois sha256() pour ralentir la procédure, c'est exactement ce à quoi sert bcrypt ou scrypt : boucler plein de fois pour ralentir l'opération et prolonger la durée de vie d'un mot de passe.
[^] # Re: AES est une mauvaise fonction de hashage !
Posté par Nicolas Boulay (site web personnel) . Évalué à 1.
Quelle différence, ici, entre utiliser AES+une clef plateforme, et un hash + un sel plateforme ?
MISC a publié un article sur l'usage de AES comme hash, et montrait que c'était une mauvaise solution, mais je ne sais plus pourquoi :)
"La première sécurité est la liberté"
[^] # Re: AES est une mauvaise fonction de hashage !
Posté par nud . Évalué à 6.
AES est bi-directionnel donc si tu trouves la clef tu peux tout décrypter directement.
Avec le hash au moins, il faut encore cracker tous les hashs car la fonction de hashage n'est pas bi-directionnelle. C'est alors la force du mot de passe en lui-même qui compte.
# apg
Posté par Lol Zimmerli (site web personnel, Mastodon) . Évalué à 4.
C'est pourquoi, quelque soit la façon de le stocker, la première mesure à prendre est un bon mot de passe. Et pour en générer, il existe un logiciel assez bien fichu: apg
Vas donc chercher
PhrodzazEwn5
dans une rainbow table!La gelée de coings est une chose à ne pas avaler de travers.
[^] # Re: apg
Posté par Fabimaru (site web personnel) . Évalué à 2.
Tellement facile à retenir qu'il faut le noter sur un post-it sous le clavier.
[^] # Re: apg
Posté par sanao . Évalué à 2.
Dans la liste des propositions de apg, j'ai toujours trouvé un mot de passe "human readable".
# Niveau 2
Posté par serianox . Évalué à 4.
On utilise du chiffrement convergent pour effectuer une comparaison exacte, on conserve la dérivation par
bcrypt
pour ralentir le brute-force, ainsi que le sel par utilisateur pour empêcher la génération de tables arc-en-ciel. :)$usersalt || AES-CBC($password || $padding, bcrypt($usersalt || $password || $padding))
# pas de mot de passe?
Posté par chubinou . Évalué à 2.
Pourquoi ne pas mettre de mot de passe?
À chaque fois que l'utilisateur veux se connecter on lui renvois un lien avec un jeton unique à son adresse mail.
De toutes façon, il oublie régulièrement son mot de passe et en demande un nouveau par mail ou a mis le même que sur 50 autres sites (ou est suffisamment geek et a un gestionnaire de mot de passe)
[^] # Re: pas de mot de passe?
Posté par pasBill pasGates . Évalué à 2.
A son addresse e-mail ? Avec un e-mail qui a de fortes chances de passer en clair sur le reseau ? Qui va arriver on ne sait quand ? (genial pour automatiser quoi que ce soit…) Si son address e-mail est recyclee comme Yahoo s'est mis a faire tu envoies le lien a un inconnu ? etc…
[^] # Re: pas de mot de passe?
Posté par claudex . Évalué à 7.
J'allais faire la même réflexion mais à partir du moment où on permet d'utiliser l'adresse mail pour récupérer le compte, ça ne change pas grand chose.
« Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche
[^] # Re: pas de mot de passe?
Posté par pasBill pasGates . Évalué à 1.
Tout depend de comment tu le fais. Si tu poses des questions (le nom de ton 1er chien, la marque de ta chaussette droite, etc…) avant d'envoyer un e-mail de reset, c'est deja bien plus difficile.
[^] # Re: pas de mot de passe?
Posté par Zylabon . Évalué à 6.
Sauf si l'attaquant est un proche, ou que t'as mis le nom de ton premier chien sur facebook… etc.
Please do not feed the trolls
[^] # Re: pas de mot de passe?
Posté par pasBill pasGates . Évalué à -2.
A toi de choisir des questions dont toi seul connait la reponse.
La securite totale a ses limites, et plus elle est haute, plus elle est compliqueee et non-user-friendly.
[^] # Re: pas de mot de passe?
Posté par Zarmakuizz (site web personnel) . Évalué à 6.
Il faut donc utiliser ces questions secrètes comme des mots de passe, en indiquant une réponse parfaitement incohérente par rapport à la question posée.
Oh wait, encore plus de mots de passe à retenir, et cette fois stockés en clair…
Commentaire sous licence LPRAB - http://sam.zoy.org/lprab/
[^] # Re: pas de mot de passe?
Posté par zebul0n (site web personnel) . Évalué à 6.
Une erreur est survenue !
Le nom de votre premier animal de compagnie doit être compris entre 2 et 8 caractères, composé uniquement de caractères alphabétiques. Fido et Milou sont exclus des possibilités.
Le nom de votre premier animal de compagnie ne peut correspondre au prénom de votre belle mère fournie en question 17.
[^] # Re: pas de mot de passe?
Posté par rakoo (site web personnel) . Évalué à 5.
Du coup au lieu de faire ça avec le compte email de l'utilisateur, il faut le faire avec son compte XMPP. Le contact est direct, les implémentations sont sécurisées (en plus tout est fait en ce moment pour que les échanges soient chiffrés).
[^] # Re: pas de mot de passe?
Posté par Spack . Évalué à 6.
Ou utiliser OpenID ?
Tu peux ainsi laisser la gestion de l'authentification à ceux qui se donnent les moyens de faire un truc sécurisé mais par la même occasion, cela contraint tes utilisateurs à créer un compte différent pour accéder au site sans compter la base d'utilisateurs qui est fournie gratuitement à des compagnies qui en tire profit.
[^] # Re: pas de mot de passe?
Posté par Krunch (site web personnel) . Évalué à 5.
On peut aussi laisser les utilisateurs s'authentifier via Facebook, Google ou autre. Pratique, sécurisé et ça permet de limiter les comptes anonymes qui sont la cause d'au moins 82,4% du spam, des virus et de la pédopornographie sur internet.
pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.
# PBKDF-2
Posté par galactikboulay . Évalué à 2.
J'ai utilisé dans un projet PBKDF-2 avec comme fonction HMAC-SHA1, 8192 itérations et une taille de salt 256 bits.
Le salt est généré aléatoirement pour chaque utilisateur.
A priori on dirait du niveau -0.5 dans la classification donnée par le journal.
# Niveau 42 : faire comme les geek
Posté par Zylabon . Évalué à 9.
Please do not feed the trolls
[^] # Re: Niveau 42 : faire comme les geek
Posté par diorcety . Évalué à 1.
A part quelques sites officiels, peu le pratique … dommage.
# Utilisation avec Postgresql
Posté par Jean-Max Reymond (site web personnel) . Évalué à 1.
Je regardais la documentation Postgresql associée au module pgcrypto: http://www.postgresql.org/docs/9.3/static/pgcrypto.html
Est ce qu'on a une sécurité maximum en utilisant les fonctions de la base de données, par exemple avec du xdes, mais en sachant qu'il passera des infos entre l'application et la base et que sans doute on pourra voir des choses en regardant les logs de postgres pour les requêtes exécutées (avec les bons droits Unix, of course) ?
# cookies
Posté par wilk . Évalué à 2.
Merci pour cette petite piqûre de rappel.
Quel est l'état de l'art pour ce qui est de l'identification automatique (par cookies) ?
# Stockage sensible
Posté par barmic . Évalué à 3.
Ou pas il peut stocker le sel uniquement en mémoire, il faut juste lui redonner à chaque lancement, d'ailleurs c'est aussi possible avec le niveau 1 où tu peut donner le mot de passe lors du lancement (bien sur jamais en paramètre dans la ligne de commande pour ne pas que ça apparaisse dans l'historique de commande ou dans
ps
). C'est plus contraignant oui, mais c'est moins chère qu'un HSM.Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)
[^] # Re: Stockage sensible
Posté par oinkoink_daotter . Évalué à 2.
Ca ne protège pas de la même chose… L'intérêt du HSM c'est que c'est lui qui fait les opérations crypto et que les éléments sensibles n'en sortent jamais (ou jamais en rouge). Tu ne vas pas mettre un HSM pour qu'après les démarrage il file gentiment à PHP le sel à utiliser pour la BDD, hein. Autant utiliser une clef usb.
Tu vas utiliser un HSM dans ce type de cas pour que :
1/ il te hashe un mot de passe utilisateur et te ressorte un hash avec sel chiffré avec une clef locale au HSM
2/ quand tu lui files un mot de passe avec le blob qu'il t'a renvoyé au 1/, il te dise ok ou ko.
[^] # Re: Stockage sensible
Posté par barmic . Évalué à 2.
Je répondais à la problématique du stockage d'une clef ou d'un sel rien de plus (c'est bien ce dont il est question dans le journal et dans ma citation). Si tu fait faire ton encryption par un HSM toute la discussion ici ne sert à rien tu utitlise ce que ton HSM te fourni (et la problématique est « juste » de trouver un bon HSM).
Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)
[^] # Re: Stockage sensible
Posté par oinkoink_daotter . Évalué à 2.
Moi ce que je dis, c'est que l'on ne se sert pas d'un HSM pour stocker une clef ou un sel si c'est pour qu'il la balance en clair à la plateforme hôte. Ca n'a aucun sens.
# Avec PHP
Posté par Laurent J (site web personnel, Mastodon) . Évalué à 9.
Si vous êtes développeurs en PHP, il y a depuis la version 5.5 des fonctions qui simplifient énormément l'utilisation et le stockage des mots de passes, évitant comme autrefois à apprendre comment paramétrer correctement mcrypt (et donc bien souvent encourageant les développeurs à revenir sur du sha1).
Donc voilà, utilisez dorénavant l'api password. ça fait du blowfish etc. Et pour ceux qui ne sont pas encore en 5.5, il y a une lib pure PHP qui fait la même chose.
Vous n'avez donc plus aucune excuse pour stocker vos mots de passe n'importe comment.
# Encore du secret partagé…
Posté par benoar . Évalué à 4.
Oui, bon, l'authentification par secret partagé (ici un mot de passe), c'est bien, c'est pas trop compliqué même si comme tu le montres, il existe beaucoup de moyens de se foirer, mais quand même, depuis un bout de temps on a inventé d'autres moyens d'authentification. Certes, il nécessitent une modification des protocoles, et ne sont pas de simples moyens de « stockage de mots de passe ». Mais ils ont souvent d'autres avantages, le premier étant par exemple de ne jamais dévoiler le mot de passe au serveur en question. Au vu de la réutilisation massive des mots de passe de la part des utilisateurs pour différents services, ça me semble une qualité pas du tout négligeable.
Comme exemple, je pense par exemple à SCRAM http://tools.ietf.org/html/rfc5802, RFC 5802. Ça se base sur TLS pour l'authentification du serveur, et permet d'authentifier l'utilisateur sans qu'il ne donne son mot de passe, et sans que le serveur puisse se faire passer pour le client pour d'autres services (c'est un peu dérivé de la propriété précédente, certes), tout en évitant bien sûr le problème de dévoilement du secret côté serveur en cas de vol de la base. En bonus, je crois (mes souvenirs sont mauvais) qu'il évite les écueils classiques du channel-binding, i.e. il indique l'information qu'on peut utiliser comme étant suffisante pour identifier la personne à partir de ce canal, afin d'éviter le MITM (bon, c'est pas clair du tout dit comme ça…) ; cf RFC 5056 http://tools.ietf.org/search/rfc5056 si vous voulez creuser.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.