2010-12-16 162 views
1

J'ai un code ici pour un système de connexion, qui est purement ou à des fins d'apprentissage, créé avec l'aide des gens de stackoverflow, et on m'a dit de ne pas stocker le sel et le hash, mais plutôt ensemble. Je me demande comment je vais comparer les mots de passe lorsque l'utilisateur essaie de se connecter. Si le sel n'est pas stocké, comment puis-je comparer les deux? Quelqu'un peut-il aider?Comment comparer les mots de passe des utilisateurs pour se connecter avec ce code?

require("constants.php"); 
$DBH = new mysqli($dbhost, $dbuser, $dbpass, $dbname); 

function createSalt() { 
    $length = mt_rand(64, 128); 
    $salt = ''; 
    for ($i = 0; $i < $length; $i++) { 
     $salt .= chr(mt_rand(33, 255)); 
    } 
    return $salt; 
} 
//Salt function created by ircmaxell 

function registerNewUser() { 
    //Check to see if  Username Is In Use// 
    $q = $DBH->prepare("SELECT id FROM users WHERE username = ?"); 
    $username = filter_var($username, FILTER_SANITIZE_STRING); 
    $data = array($username); 
    $q->execute($data); 
    $row = $q->fetch(); 

    if ($row === false) { 
     //If Username Is Not Already In Use Insert Data// 
     $hash = hash('sha256', $pass); 
     $salt = createSalt(); 
     $hash = hash('sha256', $salt . $hash . $pass); //UPDATED 
     $data = array($username, $hash, $salt); 
     $qInsert = $DBH->prepare(
      "INSERT INTO users (username, password, salt) values (?, ?, ?)" 
     ); 
     $qInsert->execute($data); //Inserts User Data Into Table// 
    } 
} 
+0

Vous pouvez ignorer la ligne '$ hash = hash ('sha256', $ pass);' – Jacco

Répondre

2

Vous avez à interroger votre base de données pour récupérer la ligne de l'utilisateur (le cas échéant), obtenir le sel et utiliser le même algorithme sur le mot de passe fourni par l'utilisateur. Si les deux hashes correspondent, l'utilisateur a fourni un bon mot de passe.

faire un code qu'il ferait quelque chose comme ceci:

$qSelect = $DBH->prepare('SELECT salt,password FROM users WHERE username = ?'); 
$qSelect->execute(); 
$qSelect->bind_result($salt, $db_password); 
$qSelect->fetch(); 

if($salt == null){ 
    // username doesn't exist 
    return; 
}  

$hash = hash('sha256', $pass); 
$hash = hash('sha256', $salt . $hash . $pass); 
if($hash == $db_password){ 
    // login ok 
} else { 
    // login nok 
} 
+0

Aurais-je besoin de stocker le sel quelque part? Parce que l'exécution du code pour le sel à nouveau ne produira pas les mêmes résultats, donc je ne peux pas penser à une autre façon de recréer le hachage. – mcbeav

+0

@mcbeav: le même sel et le même mot de passe devraient ** toujours ** produire le même hachage. – zerkms

+0

"Est-ce que je devrais stocker le sel quelque part?" - vous le faites déjà - vous le stockez dans le champ 'salt'. – zerkms

2

le même travail:

$hash = hash('sha256', $row['salt'] . hash('sha256', $pass) . $pass); 
if ($row['password'] == $hash) { 
    // the password is correct 
} 

$row a été tiré de la base de données en fonction du nom d'utilisateur et $pass est le mot de passe récupéré du formulaire.

En outre, il est inutile d'inclure le mot de passe dans le double hachage: haché et le texte brut un

$hash = hash('sha256', $salt . $pass); // this would be enough 
+0

@zerkms: ce n'est pas vraiment inutile car cela augmente la complexité pour casser le mot de passe. puisque vous devez faire deux passes de sha256. De plus, il serait difficile de craquer même un mot de passe court, car le hachage est toujours une longue chaîne, peu importe quoi. – RageZ

+0

merci! Je n'étais pas au courant de cela. Le code a été changé pour réellement ne pas stocker le sel, n'a pas vu que j'ai posté le mauvais code, mais je suppose que je dois stocker le sel ici pour que les choses fonctionnent. Le stockage du sel dans la DB va-t-il rendre cela moins sûr? – mcbeav

+0

@RageZ: en effet dans la partie, que 2 calculs est plus lent que 1, mais en effet cette chaîne plus longue n'est pas plus sécurisée (puisqu'elle a été préparée à partir des mêmes données). – zerkms

1

Questions:

1) Votre méthode pour créer un hachage de mot de passe du hachage + sel est non traditionnel. Ce n'est pas strictement un problème, ce n'est pas ce que vous vouliez. Zerkms a fait ce point assez clairement. 2) Votre insertion de base de données nécessite soit que ce nom d'utilisateur soit une colonne unique et qu'il manque une gestion des exceptions, soit qu'il soit vulnérable à une course qui entraînera plusieurs utilisateurs avec le même nom d'utilisateur et différents mots de passe (et différents ID si est une clé)

+0

Je suis désolé je ne suis pas sûr si je comprends complètement votre réponse. Pour la deuxième partie, dites-vous que la fonction vérifiant si le nom d'utilisateur est utilisé n'est pas correctement écrite? Si oui, toute idée sur la façon de résoudre ce problème? Je suis nouveau à mysqli et PDO bien que ce soit mysqli. et en ce qui concerne la première partie, pensez-vous que cela pourrait causer des problèmes avec quoi que ce soit? peut-être performace? – mcbeav