1

我试图为我的程序提供最好的密码安全性,经过一些研究,所有道路似乎都以 PHPASS 作为我的最佳选择。我正在做一些实验以了解我在做什么。进展不顺利,哈哈,据我所知,PHPASS 在密码中添加了一个随机盐,然后对其进行哈希处理,以便将其存储在数据库中,用户现在已注册!这对我来说很好用。这是我不做的部分'不明白,当用户登录时,我从数据库中检索哈希并将其与用户在登录时输入的密码生成的哈希进行比较,但这次新的哈希不同,因为它已经生成来自不同的盐?并且与存储在 DB 中的不匹配。在某处我很愚蠢,并且遗漏了其他人确实得到的明显东西。 

4

3 回答 3

2

是的,这是一个很好的库。如果您有 PHP 5.5+,则不需要,因为内置了类似的功能。

用于$hasher->CheckPassword($pass, $hash)检查密码,而不是重新散列密码。这样可以确保它使用相同的盐(盐存储在散列的开头,散列算法也是如此)。

于 2013-12-11T13:33:57.730 回答
1

PHPASS 返回一个散列,其中包含用于计算散列的算法、散列的成本、使用的,以及我认为是算法的结果,因此取决于使用的密码。

算法:

对于 bcrypt 哈希,这应该是 '$2y$',尽管 '$2x$' 和 '$2a$' 也是可能的。请参阅PHP 的 crypt() 手册。(如果可以的话,PHPASS 使用 crypt() 我相信)

成本:

04-31 范围内的 2 个字符宽的零填充值。1<<<cost>将在内部使用,这就是为什么 31 是上限(32 位可用)。

盐:

来自字母“./0-9A-Za-z”的 22 个字符。

将哈希用作盐时,不会使用剩余的字符。

以下是一些代码及其输出,可以清楚地说明它在正确使用时是如何工作的:

<?php

    echo crypt('meow', '$2y$05$' . str_repeat('.', 20) . '//meow'), PHP_EOL; // salt: ....................//
    echo crypt('meow', '$2y$05$' . str_repeat('.', 20) . '//woof'), PHP_EOL; // salt: ....................//
    echo crypt('meow', '$2y$05$' . str_repeat('.', 20) . '//oink'), PHP_EOL; // salt: ....................//

echo PHP_EOL, '###########################', PHP_EOL, PHP_EOL;

    echo $meow = crypt('meow', '$2y$05$' . str_repeat('.', 20) . '/meow'), PHP_EOL; // salt: ..................../m
    echo $woof = crypt('meow', '$2y$05$' . str_repeat('.', 20) . '/woof'), PHP_EOL; // salt: ..................../w
    echo $oink = crypt('meow', '$2y$05$' . str_repeat('.', 20) . '/oink'), PHP_EOL; // salt: ..................../o

echo PHP_EOL, '###########################', PHP_EOL, PHP_EOL;

    echo crypt('meow', $meow), PHP_EOL; // salt: ..................../m
    echo crypt('meow', $woof), PHP_EOL; // salt: ..................../w
    echo crypt('meow', $oink), PHP_EOL; // salt: ..................../o

echo PHP_EOL, '###########################', PHP_EOL, PHP_EOL;

    var_dump(
        $meow === crypt('meow', $meow),

        $woof === crypt('meow', $woof),

        $oink === crypt('meow', $oink)
    );

$2y$05$..................../.0/SFonSqiMg1jG/nWVk278LFl597ZlC
$2y$05$..................../.0/SFonSqiMg1jG/nWVk278LFl597ZlC
$2y$05$..................../.0/SFonSqiMg1jG/nWVk278LFl597ZlC

###########################

$2y$05$..................../eZ/qB29TfhKdQOwZTIrLyzBTMYOwupD6
$2y$05$..................../u45Ujx7ViT/dCkbXPqwsVuv407AA/99a
$2y$05$..................../eZ/qB29TfhKdQOwZTIrLyzBTMYOwupD6

###########################

$2y$05$..................../eZ/qB29TfhKdQOwZTIrLyzBTMYOwupD6
$2y$05$..................../u45Ujx7ViT/dCkbXPqwsVuv407AA/99a
$2y$05$..................../eZ/qB29TfhKdQOwZTIrLyzBTMYOwupD6

###########################

bool(true)
bool(true)
bool(true)
于 2013-12-11T15:24:36.323 回答
0

感谢您的帮助,我似乎现在可以正常工作了,但是如果您愿意帮我检查一下,如果可以,其他人可能会觉得它有帮助,请记住,它只是测试文件,所以如果核心没问题。

这是对密码进行哈希处理并存储密码的 REG 代码。

if(isset($_POST['submit'])) {

    $username = $_POST['username'];
    $password = $_POST['password'];
    $hash = password_hash($password, PASSWORD_BCRYPT);

    if (empty($_POST) === false){
    mysql_query("INSERT INTO `accounts` VALUES ('', '$username', '$hash') ");
        echo 'Done';
    }else{
        echo 'Not Done';
    }
}   ?>

这是登录

<?php
require('../password/lib/password.php');
require_once("connect.php");

if(isset($_POST['submit'])) {

    $username = $_POST['username'];
    $safe_username = mysql_real_escape_string($username);
    $password = $_POST['password'];

    $query = "SELECT * FROM accounts WHERE username = '$safe_username'";
    $result = mysql_query($query);
    $row = mysql_fetch_assoc($result);
    $hash = $row['password'];

    if (password_verify($password, $hash)) {
        echo 'Logged in';
    } else {
        echo 'Not logged in';
    }

} else {
    echo " Not submitted";
}

你怎么看?

于 2013-12-11T20:03:42.387 回答