简体   繁体   中英

Simple but safe password hashing

I'm looking for a simple (or as simple as possible) yet secure method for hashing and salting a users password when submitting it to the database and then retrieving from the database. Having spent the past 3 hours researching, there are literally hundreds of different methods that each person will say is the best method.

I'm looking for a relatively simple method that will also keep users accounts secure. Obviously the term secure can be interpreted differently, but i just want it, at the very least, be very difficult for a would-be hacker (or whatever you'd call these saddo's) to gain access to a users account.

I appreciate that i should have at least tried a few things, but they all seem so convoluted and overly secure for my purpose.

I tried using password_hash() but it appears i'm running an earlier PHP version than 5.5. I understand there are issues with the code below, but it's simply a starting point for a person project i'm working on in order to better learn PHP.

Current registration form

$username = $_POST['username'];
$password = $_POST['password'];

try {   

    $result = $db->prepare("INSERT INTO 
                            user_info 
                            SET 
                            username = :user,
                            pass = :pass
                            ");
    $result->bindParam(':user', $username);
    $result->bindParam(':pass', $password);
    $result->execute();
}

catch (Exception $e) {
    echo "Could not create username";
}

if (isset($_POST['submit'])) { 
    foreach ($_POST as $field) {
        if (empty($field)) {
            $fail = true;
        }
        else {
            $continue = false;
        }
    }
    if ($field == $fail) {
        echo "You must enter a username and/or password";
    }
    else {
        echo "Your account has been successfully created.";
    }
     }

The login logic

$username = $_POST['username'];          
$password = $_POST['password'];

try {   

    $result = $db->prepare("SELECT username, pass FROM user_info WHERE username = :user AND BINARY pass = :pass");
    $result->bindParam(':user', $username);
    $result->bindParam(':pass', $password);
    $result->execute();
    $rows = $result->fetch(PDO::FETCH_NUM);
}

catch (Exception $e) {
    echo "Could not retrieve data from database";
    exit();
}

if ($password = $rows) {
    session_start();
    $_SESSION['username'] = $_POST['username'];
    $_SESSION['loggedin'] = true;
    include("inc/redirect.php");

} else {
    if (isset($_POST['login'])) {
        echo "Username or password incorrect (passwords are case sensitive)";
    }
}

Use sha1 function http://www.php.net/manual/en/function.sha1.php

It's really simple. Pass the password in input parameter then save it in the database.

When you want to check if password is correct you just have to compare the sha1(password) with the stored value.

Example :

$passwordEncrypted = sha1($password)

save $passwordEncrypted in your database

When the user want to login :

check this condition :

if (sha1($password) ==$passwordEncrypted )

Here is the complete code :

$username = $_POST['username'];

$password = $_POST['password'];
$passwordEncrypted = sha1($password) 

    try {   

        $result = $db->prepare("INSERT INTO 
                                user_info 
                                SET 
                                username = :user,
                                pass = :pass
                                ");
        $result->bindParam(':user', $username);
        $result->bindParam(':pass', $passwordEncrypted);
        $result->execute();
    }

    catch (Exception $e) {
        echo "Could not create username";
    }

    if (isset($_POST['submit'])) { 
        foreach ($_POST as $field) {
            if (empty($field)) {
                $fail = true;
            }
            else {
                $continue = false;
            }
        }
        if ($field == $fail) {
            echo "You must enter a username and/or password";
        }
        else {
            echo "Your account has been successfully created.";
        }
         }

Use salt and sha256 encryption algorithm

<?php
// create user
$password = $_POST['password'];
$salt = mcrypt_create_iv(22, MCRYPT_DEV_URANDOM);
$pass = hash("sha256", $salt.$password.$salt);
// save salt and password hash into database

// to validate user
// 1 - get salt and password hash from database
// 2 - prepend and append salt to the posted password
// 3 - encrypt with the same algorithm
// 4 - compare with stored password hash. 

With password_hash() you are on the right track. For PHP versions 5.3.7 - 5.5 you can use the compatibility pack , later when you switch to a newer PHP version, you can simply remove this php file from your project and the code will still run.

// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);

// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);

Even for lower PHP versions than 5.3.7 you can use the compatibility pack‌​. You only have to edit line 55 and change the algorithm from sprintf("$2y$%02d$", $cost); to sprintf("$2a$%02d$", $cost); . This is of course not optimal, but it is the best you can do for PHP between 5.3 and 5.3.7.

The problem with other algorithms like SHA* or MD5 is, that they are ways too fast. It is possible to calculate about 3 Giga SHA-1 per second with common hardware, that makes brute-forcing too easy. To test a whole english dictionary you would need only a fraction of a millisecond. That's why one should use a hash algorithm with a cost factor like BCrypt or PBKDF2, they allow to control the necessary time to calculate a single hash.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM