55 votes

Aider avec le sel et le mots de passe

Je veux mettre en œuvre un sel dans mon système de connexion mais je suis un peu confus sur la façon dont cela est censé fonctionner. Je ne comprends pas la logique derrière elle. Je comprends md5 est un algorithme et toutes les fonctions que j'ai rencontré semblent pour hacher le tout. Si c'est le cas, comment peut-on obtenir le mot de passe de retour pour la comparaison? Ma grande question est, comment est-saler un des utilisateurs de mot de passe plus sûr que juste le hachage du mot de passe? Si une base de données n'a jamais été compromise, le hachage, ainsi que le sel est à la base de données. N'est-ce pas tout ce qu'un hacker aurait besoin?

J'ai aussi trouvé un autre post ici sur ALORS, où un autre développeur a dit :

"Assurer votre sel et de l'algorithme sont stockées séparément de la base de données"

Je voudrais stocker le sel dans la base de données. Est-ce vraiment un problème si je le fais?

Je suis à la recherche d'un peu d'aide pour comprendre comment cela fonctionne et quelles sont les meilleures pratiques pourrait être. Toute aide est grandement appréciée.


EDIT: Je tiens à remercier tout le monde pour leurs réponses et les idées. Même si j'ai peut-être plus confus maintenant, il a certainement été une expérience d'apprentissage pour moi. Merci encore les gars.

31voto

Michael Borgwardt Points 181658

Le point de sel est d'empêcher les attaquants d'amortir le coût d'une attaque en force brute sur l'ensemble des sites (ou, mieux encore, lors de l'utilisation d'un autre sel pour chaque utilisateur: tous les utilisateurs d'un site) à travers précalculées rainbow tables.

Avec la plaine de hachage, un attaquant peut calculer une telle table une fois (une très longue, coûteuse) et ensuite l'utiliser pour trouver rapidement les mots de passe pour n'importe quel site. Quand un site utilise un fixe, le sel, l'attaquant a pour calculer une nouvelle table spécialement pour ce site. Quand un site utilise une autre de sel pour chaque utilisateur, l'attaquant peut cesser de s'embêter avec "rainbow tables" - il va falloir que par la force brute de chaque mot séparément.

Stocker les sels séparément n'est pas nécessaire pour profiter de cet avantage. En théorie, il serait encore plus sûr, car elle permettrait de neutraliser la faiblesse de dictionnaire ou à court de mots de passe. Dans la pratique, il n'en vaut pas la peine avec car à la fin de la journée, vous avez besoin d'accéder aux sels de quelque part pour vérifier les mots de passe. Aussi, en essayant de les séparer conduirait à des systèmes plus complexes et les plus complexes, un système est, les plus de possibilités pour des trous de sécurité.

Edit: Mes recommandations concrètes:

  • Générer une pseudo-aléatoire de sel pour chaque utilisateur et de les stocker dans la DB
  • Utiliser un bcrypt-en fonction de hachage
  • idéalement, ne pas mettre en œuvre vous-même, utiliser une bibliothèque existante au lieu

19voto

Andrew Moore Points 49765

Une fonction de hachage retourne toujours la même valeur pour la même chaîne d'entrée. Disons que mon utilisateur (Alice) a le mot de passe secret. Le hachage secret l'aide md5() conduit à la suite de hachage

5ebe2294ecd0e0f08eab7690d2a6ee69

À l'aide d'un dictionnaire (une liste de mots courants et mot de passe) ou l'un des différents sites que vous offrir ce service, l'attaquant (Mallory) peut facilement trouver le mot de passe est secret lorsqu'il voit dans son dictionnaire qu' 5ebe2294ecd0e0f08eab7690d2a6ee69 = secret.

Le processus de salage avant le hachage rend plus difficile d'utiliser une attaque par dictionnaire sans connaître votre sel. Considérez les points suivants:

<?php
$salt = '@!#%$@#$@SADLkwod,sdaDwqksjaoidjwq@#@!';
$hash = md5($salt . 'secret');

Le résultant de hachage est désormais b58ad809eece17322de5024d79299f8a mais Alice mot de passe est toujours secret. Maintenant, si Mallory obtient ses mains sur le salé de hachage, les chances sont qu'elle ne va pas trouver la réponse dans son dictionnaire. Si elle le fait, le dictionnaire lui donner la mauvaise réponse.

Ne conservez jamais statique de sel dans votre base de données. De préférence, les stocker avec votre configuration de l'application (qui d'ailleurs ne devrait pas être disponible sur le web).

Si vous allez utiliser une dynamique de sel, vous allez avoir besoin d'utiliser la base de données. Utiliser une valeur non nulle de la colonne de l'existant valide les données de votre sel (blowfish-chaîne cryptée de nom d'utilisateur basée sur un secret de la clé de chiffrement est généralement cryptographique sécurisé). Ne pas utiliser une colonne séparée pour le sel. Si vous ne pouvez pas utiliser une colonne existante, incorporer le sel dans la même colonne que votre hash. Par exemple, utiliser les 32 premiers caractères de votre 128-bits de sel, puis les 40 dernières pour votre 160 bits de hachage. La fonction suivante va générer un tel hash:

function seeded_sha1($string, $seed_bits) {
    if(($seed_bits % 8) != 0) {
        throw new Exception('bits must be divisible by 8');
    }

    $salt = '';
    for($i = 0; $i < $seed_bits; $i+=8) {
        $salt .= pack('c', mt_rand());
    }

    $hexsalt = unpack('h*hex', $salt);

    return $hexsalt['hex'] . sha1($salt . $string);
}

function compare_seeded_sha1($plain, $hash) {
    $sha1 = substr($hash, -40);
    $salt = pack('h*', substr($hash, 0, -40));

    $plain_hash = sha1($salt . $plain);
    return ($plain_hash == $sha1);
}

Si un intrus pénètre dans votre base de données en utilisant SQL injection, au moins les hachages il/elle récupère ne sera pas utile car il/elle n'aura pas accès à la configuration de votre application. Si votre serveur est enracinée, c'est assez beaucoup de jeu sur n'importe ce que vous faites.

Remarque: Il existe d'autres types d'attaques possibles sur md5() qui est pourquoi vous utilisez le plus sûr algorithme de hachage, sha1() par exemple. Ou, mieux encore, utiliser le Portable PHP hachage de mot de passe-cadre, qui a été conçu avec la sécurité à l'esprit et est rétro-compatible avec pratiquement n'importe quel version de PHP.

require('PasswordHash.php');

$pwdHasher = new PasswordHash(8, FALSE);

// $hash is what you would store in your database
$hash = $pwdHasher->HashPassword( $password );

// $hash would be the $hashed stored in your database for this user
$checked = $pwdHasher->CheckPassword($password, $hash);
if ($checked) {
    echo 'password correct';
} else {
    echo 'wrong credentials';
}

15voto

Rich Points 4452

Oubliez l'utilisation de sels (en partie pour la raison que vous mentionnez), l'utilisation bcrypt à la place:

Pour une bonne explication, voir: http://codahale.com/how-to-safely-store-a-password/

7voto

indiv Points 7403

Les autres réponses sont bonnes, donc je vais juste jeter dans un point de détail que personne n'a mentionné. Vous ne voulez pas utiliser le même sel pour chaque mot de passe parce qu'alors, si deux personnes ont le même mot de passe, ils ont le même hash. Est d'exposer des informations qu'un attaquant peut exploiter.

Vous pouvez utiliser le même sel pour chaque utilisateur, ainsi que Juraj est une bonne idée de combiner le mot de passe avec d'autres non-évolution des champs de base de données (propre à un utilisateur). Mais attention, car cette information est liée au mot de passe. Si vous étiez à hacher le nom d'utilisateur + mot de passe afin de garantir un hachage unique, vous ne seriez pas en mesure de changer le nom d'utilisateur sans créer un nouvel utilisateur et d'exiger d'eux pour définir un nouveau mot de passe.

Comme exemple d'avoir un unique sel par l'utilisateur et de le ranger aux côtés du hachage de mot de passe, je vais souligner /etc/shadow sur votre système Linux.

root@linux:/root# cat /etc/shadow | grep root
root:$1$oL5TTZxL$RhfGUZSbFwQN6jnX5D.Ck/:12139:0:99999:7:::

Ici, le oL5TTZxL est le sel et RhfGUZSbFwQN6jnX5D.Ck/ est la valeur de hachage. La plaine de texte mot de passe est root dans ce cas, et l'algorithme de hachage mon système est le MD5 BSD algorithme de mot de passe. (systèmes plus récents que le mien ont de meilleurs algorithmes de hachage)

5voto

brian Points 728

Vous n'avez pas le mot de passe à des fins de comparaison. Vous chiffrer le mot de passe lors de leur tentative de connexion et de comparer la valeur stockée avec la nouvelle valeur chiffrée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X