使用pbkdf2哈希算法通过https://defuse.ca/php-pbkdf2.htm验证用户

时间:2013-01-15 12:48:38

标签: php hash login web salt

我目前正在使用md5在用户输入登录电子邮件和密码后对其进行身份验证:

if($_POST['submit']=='Login')
{
    // Checking whether the Login form has been submitted

// Will hold our errors
$err = array();


if(!$_POST['email'] || !$_POST['main_password'])
    $err[] = 'All the fields must be filled in!';

if(!count($err))
{
    // Make this an integer.
    $_POST['rememberMe'] = (int)$_POST['rememberMe'];

    try {

        $sql = "SELECT id,email FROM ld_customers WHERE email = :cust_email AND password = :cust_password";
        $stmt = $iws_db->prepare($sql);


        $stmt->bindParam(':cust_email', $_POST['email'], PDO::PARAM_STR, 255);
        $stmt->bindParam(':cust_password', md5($_POST['main_password']) , PDO::PARAM_STR, 256);

        $stmt->execute();   
        $row = $stmt->fetch();

    if($row['email'])
    {

        // If everything is OK login and write the users data to the session.
        $_SESSION['email']=$row['email'];
        $_SESSION['id'] = $row['id'];
        $_SESSION['rememberMe'] = $_POST['rememberMe'];

        // Store some data in the session

        setcookie('iwsRemember',$_POST['rememberMe']);
    }

    else $err[]='Wrong email and/or password!';

    /*** close the database connection ***/
    $iws_db = null;
    }
    catch(PDOException $e)
    {
    echo $e->getMessage();
    }
}

if($err)
$_SESSION['msg']['login-err'] = implode('<br />',$err);
// Save the error messages in the session

header("Location: index.php");
    exit;
}

但我想现在使用https://defuse.ca/php-pbkdf2.htm PBKDF2 进行身份验证。以下是代码片段:

    <?php

define("PBKDF2_HASH_ALGORITHM", "sha256");
define("PBKDF2_ITERATIONS", 10000);
define("PBKDF2_HASH_BYTES", 24);
define("PBKDF2_SALT_BYTES", 24);

define("HASH_SECTIONS", 4);
define("HASH_ALGORITHM_INDEX", 0);
define("HASH_ITERATION_INDEX", 1);
define("HASH_SALT_INDEX", 2);
define("HASH_PBKDF2_INDEX", 3);

function create_hash($password)
{
    // format: algorithm:iterations:salt:hash
    $salt = base64_encode(mcrypt_create_iv(PBKDF2_SALT_BYTES, MCRYPT_DEV_URANDOM));     
    return PBKDF2_HASH_ALGORITHM . ":" . PBKDF2_ITERATIONS . ":" .  $salt . ":" . 
        base64_encode(pbkdf2(
            PBKDF2_HASH_ALGORITHM,
            $password,
            $salt,
            PBKDF2_ITERATIONS,
            PBKDF2_HASH_BYTES,
            true
        ));
}

function validate_password($password, $good_hash)
{
    $params = explode(":", $good_hash);
    if(count($params) < HASH_SECTIONS)
       return false; 
    $pbkdf2 = base64_decode($params[HASH_PBKDF2_INDEX]);
    return slow_equals(
        $pbkdf2,
        pbkdf2(
            $params[HASH_ALGORITHM_INDEX],
            $password,
            $params[HASH_SALT_INDEX],
            (int)$params[HASH_ITERATION_INDEX],
            strlen($pbkdf2),
            true
        )
    );
}




function slow_equals($a, $b)
{
    $diff = strlen($a) ^ strlen($b);
    for($i = 0; $i < strlen($a) && $i < strlen($b); $i++)
    {
        $diff |= ord($a[$i]) ^ ord($b[$i]);
    }
    return $diff === 0; 
}

function pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output = false)
{
    $algorithm = strtolower($algorithm);
    if(!in_array($algorithm, hash_algos(), true))
        die('PBKDF2 ERROR: Invalid hash algorithm.');
    if($count <= 0 || $key_length <= 0)
        die('PBKDF2 ERROR: Invalid parameters.');

    $hash_length = strlen(hash($algorithm, "", true));
    $block_count = ceil($key_length / $hash_length);

    $output = "";
    for($i = 1; $i <= $block_count; $i++) {
        // $i encoded as 4 bytes, big endian.
        $last = $salt . pack("N", $i);
        // first iteration
        $last = $xorsum = hash_hmac($algorithm, $last, $password, true);
        // perform the other $count - 1 iterations
        for ($j = 1; $j < $count; $j++) {
            $xorsum ^= ($last = hash_hmac($algorithm, $last, $password, true));
        }
        $output .= $xorsum;
    }

    if($raw_output)
        return substr($output, 0, $key_length);
    else
        return bin2hex(substr($output, 0, $key_length));
}
?>

我试着用这种方式实现这个:

  if($_POST['submit']=='Login')
    {
        // Checking whether the Login form has been submitted

    // Will hold our errors
    $err = array();


    if(!$_POST['email'] || !$_POST['main_password'])
        $err[] = 'All the fields must be filled in!';

    if(!count($err))
    {
        // Make this an integer.
        $_POST['rememberMe'] = (int)$_POST['rememberMe'];

        try {

            $sql = "SELECT id,email FROM ld_customers WHERE email = :cust_email";
        $stmt = $iws_db->prepare($sql);

        /*** bind the paramaters ***/
        $stmt->bindParam(':cust_email', $_POST['email'], PDO::PARAM_STR, 255);




        $stmt->execute();

        $row = $stmt->fetch();

                    if(!validate_password($_POST['main_password'], $row['password']))
                    {
                     exit("Password error!");
                    }
                     else
                    {
                     if($row['email'])
             {
              // If everything is OK login and write the users data to the session.
        $_SESSION['email']=$row['email'];
        $_SESSION['id'] = $row['id'];
        $_SESSION['rememberMe'] = $_POST['rememberMe'];

        // Store some data in the session

        setcookie('iwsRemember',$_POST['rememberMe']);    

        }
                    else
                    {
                    $err[]='Wrong email and/or password!';
                    }
                   }


    /*** close the database connection ***/
    $iws_db = null;
    }
    catch(PDOException $e)
    {
    echo $e->getMessage();
    }
}

if($err)
$_SESSION['msg']['login-err'] = implode('<br />',$err);
// Save the error messages in the session

header("Location: index.php");
exit;

我没有成功实现它,每次退出说密码错误!! 我认为问题是获取存储的加密密码并将其与用户输入的密码进行比较。

1 个答案:

答案 0 :(得分:0)

我认为应该是这样的:

    $sql = "SELECT id,email FROM ld_customers WHERE email = :cust_email";
    $stmt = $iws_db->prepare($sql);


    $stmt->bindParam(':cust_email', $_POST['email'], PDO::PARAM_STR, 255);

    $stmt->execute();   
    $row = $stmt->fetch();
if($row['email'])
{
  if(!validate_password($_POST['main_password'], $row['password']))
  {
     exit("Password error!");
  }
  else
  {
    echo'Logged in!';
  }
}
else
   echo"email doesn't exist";

您正在创建MD5哈希,而不是使用库的功能。