Un «si mot de passe == XXXXXXX» est-il suffisant pour une sécurité minimale?

20

Si je crée une connexion pour une application qui présente un risque de sécurité moyen à faible (en d'autres termes, ce n'est pas une application bancaire ou quoi que ce soit), est-il acceptable pour moi de vérifier un mot de passe entré par l'utilisateur en disant simplement quelque chose comme:

if(enteredPassword == verifiedPassword)
     SendToRestrictedArea();
else
     DisplayPasswordUnknownMessage();

Il semble facile d'être efficace, mais cela ne me dérangerait certainement pas si c'était tout ce qu'il fallait. Une simple vérification du combo nom d'utilisateur / mot de passe est-elle suffisante?

Mise à jour: Le projet particulier se trouve être un service Web, la vérification est entièrement côté serveur et n'est pas open-source. Le domaine change-t-il la façon dont vous traiteriez cela?

Morgan Herlocker
la source
3
cela dépend d'où vient validPassword? s'il est codé en dur, vous ne pourrez pas configurer / changer le mot de passe sans changer le code. S'il provient d'un fichier de configuration, il sera visible par toute personne y accédant.
Alb
1
"une vérification du nom d'utilisateur / mot de passe est-elle suffisante" pour faire quoi?
Chris
3
@opinion: il semble peu probable que ce soit pire que de ne pas avoir de connexion. Veuillez fournir un raisonnement pour une telle affirmation.
Morgan Herlocker
1
Votre terminologie est incorrecte, lorsque vous comparez un mot de passe, vous le vérifiez, sans vous assurer qu'il est valide. Veuillez prendre le temps de comprendre la différence.
billy.bob
1
Cela implique un stockage de mot de passe en texte brut, ce qui est irresponsable. Cela implique également d'alerter un utilisateur que le mot de passe était incorrect, ce qui fournit à un attaquant potentiel trop d'informations. Vous devez toujours être ambigu, c'est-à-dire "Login ou mot de passe incorrect".
Rein Henrichs

Réponses:

26

Pas sans SSL

Ce n'est pas sécurisé si le mot de passe est envoyé sur le réseau en texte brut. Le hachage du mot de passe côté serveur n'est pas non plus sécurisé si le mot de passe est envoyé sur le réseau en texte brut.

Étant donné que la <input type="password"/>balise HTML envoie son contenu en texte brut, ce sera un problème quelle que soit la façon dont vous stockez le mot de passe sur le serveur, sauf si votre site Web utilise SSL pour transmettre le mot de passe.

(L'authentification HTTP, qui fait apparaître une boîte de dialogue dans le navigateur demandant un mot de passe, peut être en texte clair ou non, selon les mécanismes d'authentification communs au serveur et au navigateur. Cela pourrait donc être un moyen d'éviter cela sans utiliser SSL.)

Pas si les administrateurs du site sont suspects

Maintenant, en supposant que vous utilisez HTTPS pour faire le site Web, cela pourrait être sécurisé si vous faites confiance aux administrateurs de votre site (qui peuvent lire les mots de passe en texte brut) et aux autres personnes qui ont accès à la machine pour se comporter correctement. Maintenant, il peut être évident qu'ils peuvent faire tout ce qu'ils veulent avec votre site Web (car ils l'administrent), mais s'ils peuvent lire le mot de passe, ils peuvent également utiliser les paires identifiant / mot de passe volées sur les sites d'autres personnes.

Un moyen qui protège les mots de passe de l'administrateur

Un moyen sûr de stocker et de vérifier les mots de passe est le suivant:

def change_password user, new_password
  salt = random(65536).to_s(16) #will be 4 characters long
  password_hash = salt + hash(salt + new_password)
  store(user,password_hash)
end

def does_password_match? user, entered_password
  correct_password_hash = retrieve(user)
  salt = correct_password_hash[0...4]
  entered_password_hash = salt + hash(salt + entered_password)
  return correct_password_hash == entered_password_hash
end

Pour la fonction de hachage, essayez d'utiliser quelque chose de fort et quelque chose qui n'a pas encore de bonnes tables arc-en-ciel à l'état sauvage. Vous pouvez modifier la longueur du sel si nécessaire autour des tables arc-en-ciel.

Selon l'environnement dans lequel vous vous trouvez, la variabilité de la latence de votre réseau et si les noms d'utilisateurs sont censés être connus du public, vous souhaiterez peut-être calculer un autre chemin de code hash('0000'+entered_password)si l'utilisateur n'existe pas, afin d'empêcher les attaquants de déterminer quels noms d'utilisateur sont valides en fonction du temps qu'il faut déterminer que le mot de passe est incorrect.

Ken Bloom
la source
1
Bons conseils :) En ce qui concerne SSL, nous étions tenus de concevoir quelque chose qui fonctionnerait à l'état sauvage , et nous avons simplement utilisé la cryptographie asymétrique pour coder le mot de passe (nécessite Javascript), puis le décoder sur le serveur. Le sel + hachage se produit alors normalement. De plus, puisque la clé publique est envoyée avec la page Web, elle peut changer arbitrairement souvent.
Matthieu M.
1
@Matthieu M .: Quand quelqu'un peut truquer votre page Web, il peut également y changer la clé publique en une clé où il connaît lui-même la clé privée correspondante. Votre idée ne peut donc aider que contre les attaques de lecture passives, pas contre l'homme du milieu.
Paŭlo Ebermann
@Paulo: oui, je suis d'accord que SSL ne concerne pas seulement le cryptage, mais aussi le certificat, malheureusement je n'appelle pas les plans ici, et quand les gens disent qu'ils veulent utiliser la page Web avec une http://connexion régulière ... c'est frustrant: /
Matthieu M.
@Matthieu: Cela signifie-t-il que vous envoyez public_key dans le cadre de la page Web publique, calculez encrypt(entered_password, public_key)sur le client et envoyez ce résultat au serveur, qui fonctionne does_password_match?(user, decrypt(encrypted_password, private_key))?
Ken Bloom
@Ken: plus ou moins, vous avez le bon cryptage. Pour faire correspondre le mot de passe, c'est plus does_password_match(user, salt, decrypt(encrypted, key)), avec le sel selon l'utilisateur. Comme je l'ai dit, le problème évident est le manque de protection de l'homme au milieu.
Matthieu M.
52

Cela suggérerait que vous gardiez les mots de passe en texte ouvert, ce qui est non-non, même dans les scénarios de faible sécurité.

Vous devriez plutôt avoir:

if(hash(enteredPassword) == storedHash)

Vous pouvez utiliser un hachage simple comme par exemple MD5

vartec
la source
22
+1 pour le hachage du mot de passe. Mais j'ajouterais au moins du sel aussi. Sinon, puisque les utilisateurs vont réutiliser les noms d'utilisateur et les mots de passe entre les systèmes, la violation de votre application de faible sécurité peut permettre à un attaquant de violer une application de sécurité beaucoup plus élevée. Le récent piratage de HBGary, par exemple, a réussi à compromettre le système CMS exécutant leur site Web et à le transformer en accès root à leurs serveurs en partie parce que le système CMS à faible sécurité n'ajoutait pas de sel aux hachages arstechnica.com/tech-policy/ news / 2011/02 /…
Justin Cave
1
D'accord ... considérez ce qui suit ... "chaînes JavaFile.class | grep -i mot de passe"
Bill
Quel est le problème avec le mot de passe en texte brut s'il n'est utilisé qu'une seule fois?
10
@Tim, car les utilisateurs n'utiliseront pas le mot de passe une seule fois. Les études montrent systématiquement que les utilisateurs réutilisent les mots de passe plusieurs fois (par exemple, theregister.co.uk/2011/02/10/password_re_use_study ), peu importe le nombre de fois où on leur dit de ne pas le faire.
Scott
3
@Tim: en plus, ouvrez simplement votre exe, dll, etc, dans un éditeur de texte, et vous verrez probablement votre mot de passe juste là.
Gus Cavalcanti
14

Je suis d'accord avec ceux qui suggèrent le hachage, mais il y a aussi une roue que vous réinventez ici. Selon la plate-forme, vous pouvez probablement trouver un outil de gestion des rôles / utilisateurs qui couvre toutes les tâches de gestion des utilisateurs en toute sécurité et sans nécessiter trop d'intervention de votre part.

glénatron
la source
Je viens de découvrir les fournisseurs d'adhésion ASP.Net mais je les regardais en pensant "combien de fois ai-je perdu mon temps à mettre en œuvre quelque chose comme ça?"
glenatron
8

La sécurité est un sujet très délicat, en particulier parce qu'il doit y avoir un équilibre entre incommoder vos utilisateurs et s'assurer que leurs informations sont en sécurité. En règle générale, la formule du niveau de sécurité dont vous avez besoin est fonction de l'importance des données. En bref:

isSecuritySufficient = effortToBreak > rewardForBreaking

Un malentendu courant au sujet des gens qui font de mauvaises choses est ce qu'ils recherchent. La plupart d'entre eux cherchent à détruire la confiance . Vous devez toujours faire tout votre possible pour protéger la confiance de vos utilisateurs. Cela consiste en partie à faire preuve de diligence raisonnable pour vous assurer que leur identité est en sécurité. Ils se soucient peut-être moins des données qu'ils stockent, mais ils se soucient de leur identité, même au seuil de sécurité le plus bas.

Il existe un certain nombre d'options à faible coût (à mettre en œuvre et à impact pour l'utilisateur) disponibles. L'un d'eux est le hachage du mot de passe au strict minimum. Tout service qui stocke quelque chose d'aussi sensible qu'un mot de passe en texte brut mérite l'embarras d'être piraté.

Principes généraux de protection par mot de passe

  • Ne stockez jamais les mots de passe en texte brut
  • Hachage à l'aide d'une fonction de hachage sécurisée comme SHA-1 ou même SHA-512 (même MD5 est trop facile à trouver un hachage correspondant)
  • Utilisez une valeur de sel d'application. Le sel est un octet aléatoire ajouté à un mot de passe pour le rendre plus difficile à deviner. Le sel doit être généré au moment de l'exécution et en utilisant les informations sur la machine comme valeur de départ plutôt que stocké et référencé de quelque manière que ce soit.
  • Utilisez une valeur de sel spécifique à l'utilisateur. Utilisez-le en conjonction avec votre sel d'application.
  • Chiffrez toutes les demandes d'authentification qui transitent sur un réseau. Cela signifie utiliser SSL pour les applications Web.

Puisque vous utiliseriez SSL pour l'authentification, vous voulez au moins crypter toutes les pages qui traitent également du compte de l'utilisateur. Cela permet de protéger autant que possible l'identité d'un utilisateur.

Remarque sur la gestion des mots de passe : les utilisateurs oublient parfois leur mot de passe. La pire chose que vous puissiez faire est de leur envoyer leur mot de passe par e-mail. Si vous appliquez les principes décrits ci-dessus, vous ne pourrez pas le faire de toute façon. Il est préférable de fournir un moyen de réinitialiser leur mot de passe en utilisant un lien envoyé à leur adresse e-mail enregistrée. Ce lien de réinitialisation aura un code d'utilisation unique pour garantir que la personne accédant à la page est bien elle.

Berin Loritsch
la source
1
Au début, j'ai été vraiment frappé par l'idée de sel d'application + sel d'utilisateur, mais plus j'y pense, moins je suis convaincu. Si vous avez utilisé, disons, 4 caractères de sel d'application et 4 de sel d'utilisateur, la différence entre cela et 8 caractères de sel d'utilisateur est juste que la moitié du sel serait identique pour chaque utilisateur. Il semblerait qu'il serait plus sûr d'augmenter simplement la taille du sel utilisateur, plutôt que d'avoir du sel d'application. De plus, si le sel d'application est basé sur le matériel, vous ne pouvez pas mettre à niveau ou modifier le matériel sans invalider tous les mots de passe.
David Conrad
Le problème est que le sel utilisateur est inclus dans la ligne de base de données avec le mot de passe utilisateur. Si une mauvaise personne sait à quoi sert un sel (et elle le sait) et qu’elle le voit dans la base de données, alors elle sait comment le casser complètement. En incluant une partie dans l'application qui est calculée (de la même manière à chaque fois) au lieu d'être stockée, il est beaucoup plus difficile de casser les tables d'utilisateurs. Bien sûr, vous pouvez aller plus loin et créer un sel aléatoire pur de 1 partie et un sel calculé de 1 partie, les deux étant spécifiques à l'utilisateur.
Berin Loritsch
Ah, je vois, garder une partie du sel hors de la base de données. Cela a du sens. Je vous remercie.
David Conrad
Je ne vois pas de problème de stockage du sel par ligne, tant qu'il est unique par ligne. Voici un hachage: "fd84235a55bbfeb1585a3dd069d48127989c9753058b51b6ba2056fd6c5a0a91" (SHA256), voici le sel: "671254bdf7944f8fa88e6c9913b948ee". Pensez-vous pouvoir obtenir le mot de passe? Il n'y a pas de table arc-en-ciel pour ce sel (même si on vous donne le sel), vous êtes coincé en le forçant brutalement.
Bryan Boettcher
3

C'est bien, sauf si le mot de passe est utilisé pour autre chose. Il y a toujours un risque que l'utilisateur décide qu'il peut réutiliser le mot de passe, donc ce serait encore mieux avec:

if(hash(enteredPassword) == hashOfValidPassword)

Si c'est pour vous ou pour quelqu'un qui sait que le mot de passe est stocké en texte brut, alors ça va.


la source
1
Comme dans le commentaire de Justin Cave à la réponse de Vartec, utilisez du sel, donc if (hash (enteredPassword + salt) == hashOfValidSaltedPassword)- et notez que +c'est probablement une concaténation, pas un ajout. Cela entrave vraiment l'utilisation des tables arc-en-ciel, qui sont des tables de hachage de mots de passe probables.
David Thornley
si tout ce que vous recherchez est un hachage, ne pourrait-il pas simplement parcourir une boucle de chaînes possibles jusqu'à ce que l'on génère le même hachage que le hachage stocké? Il existe de nombreuses chaînes qui pourraient correspondre au même hachage, après tout.
Morgan Herlocker
@Prof Plum: Il est très difficile de trouver des collisions si l'algorithme de hachage est bon. C'est la base de la cryptographie moderne: ce sont essentiellement des fonctions unidirectionnelles.
3

Le code source est-il disponible? Même si ce n'est pas le cas, je suis sûr que le mot de passe pourrait être trouvé dans les instructions de la machine au cas où le binaire serait disponible. Je recommanderais de faire une somme de contrôle et de comparer cela à la place.

Ne négligez jamais la sécurité même si elle n'est pas très importante à votre avis.

Anto
la source
2
Oui, mauvaise idée s'il s'agit d'un projet open source :)
-1 - Si vous pensez qu'avoir la source fait une différence, vous ne savez rien de la sécurité.
mattnz
1

Absolument pas. Lisez -le , il décrit comment les pirates ont piraté un site Web de sécurité. Vous envisagez de vous avoir comme le maillon le plus faible de la chaîne.

Dave
la source
0

Il a été noté dans quelques réponses que vous ne devez pas stocker le mot de passe lui-même, mais un hachage - et vous devez utiliser SSL.

Vous pouvez dire, quel est le gros problème? Si ma demande est piratée, cela ne pose pas grand problème. Eh bien, c'est un modèle assez courant pour les utilisateurs de réutiliser le même mot de passe sur tous les sites. Si un pirate informatique piratait votre site et avait accès aux mots de passe des utilisateurs, le pirate informatique pourrait se faire passer pour un grand nombre de ces utilisateurs sur d'autres sites plus importants pour ces utilisateurs. Le piratage de votre site pourrait donc être la première étape pour un pirate pour accéder aux informations bancaires des utilisateurs.

Et le hachage du mot de passe ne suffit pas. Vous devez le hacher avec un sel. Les pirates ont des tables de recherche de hachage inversées, donc pour un hachage donné, ils peuvent trouver un mot de passe correspondant.

Si vous choisissez de ne pas implémenter ces fonctionnalités, vous devez informer les utilisateurs de ce manque de sécurité, en les encourageant à ne pas utiliser le même mot de passe qu'ils utilisent ailleurs.

Pete
la source
-2

Tant que c'est côté serveur .. Alors oui.

Si vous voulez un peu plus de sécurité, optez pour https et chiffrez \ hachage le mot de passe dans la base de données.

Crétins
la source
3
Pourquoi supposer qu'il s'agit d'une application Web?
Chris
Bon point! Je viens de faire.
Morons
4
-1 même si c'est côté serveur ce n'est toujours pas ok.
GSto