如何检查密码是否为哈希值 - PHP

3
我有一个用户类,它进行了一些简单的验证。我想使用phpass将所有密码存储为哈希值。但是,我不希望User类设置哈希值,这应该由其他函数来完成。所以,如果我有一个简单的名为setPassword的函数,如何确保密码是哈希值呢?is_binary行吗?我这里并没有比较哈希值,我只是想确保密码是哈希值,md5或sha1或其他类型都无所谓。我只是想确保密码是哈希值。

示例:

class User
{
    private password = NULL;
    private $errors = array();

    public function setPassword($password)
    {
        // make sure password is a hash...pseudo code
        if (!password_is_hash($password))
        {
            $this->errors[] = 'Invalid password';
            return $this;
        }
        $this->password = $password;
        return $this;
    } 

    public function getPassword()
    {
        return $this->password;
    }
}

3
“is a hash”是什么意思?md5('foo')会输出哈希值acbd18db4cc2f85cedef654fccc4a4d8,它本身也可以成为一个完全有效的密码...从技术上讲,任何 32个字符十六进制字符串都是一个md5哈希值,尽管你无法确定它是哪些信息的哈希。 - Marc B
我猜有没有办法确保密码不是像dog、coming in或going out这样的常见词汇?我猜用户可能会将其作为密码发布,但大多数人不会这样做。我需要setPassword函数来确保进出数据库的内容是经过哈希处理的密码,而不是明文密码,例如myfavoritepassword。 - user2707535
通常,密码哈希应该是 验证 的一部分,而不是领域对象。我只会传入一个已经哈希过的密码。 - AlexP
你不会比较密码。你需要使用你选择的哈希算法对用户提供的任何内容进行哈希处理。如果从用户输入得到的哈希值与你在数据库中保存的哈希值匹配,则表示他们提供了正确的密码。 - Marc B
我认为你的问题在于你说“假设哈希函数失败”。如果它失败了,它不会默默地失败。哈希函数会抛出一个错误。它永远不会只是返回密码。除非你正在编写自己的哈希函数。提示:不要这样做。有很多免费且非常安全的版本可用。如果你已经在使用现有版本,那么没有理由认为哈希库比程序的任何其他部分更容易神秘地“失败”。 - loneboat
显示剩余2条评论
4个回答

13

我不确定它总是正确/安全的,但你可以使用password_get_info函数。如果这个方法无法猜测算法,我们可以假设该字符串不是哈希值。

function password_is_hash($password)
{
    return password_get_info($password)['algoName'] !== 'unknown';
}

对于像sha1或md5这样的简单算法,这种方法不起作用。


0

所有的哈希值都只是字符串。因此您无法精确地检查它是否为哈希值。MD5哈希看起来像a23b34c45d56a23b34c45d56a23b34c4,您无法将其与myrealreallooooongpassword111222区分开来。


如果您知道正在使用的哈希算法怎么办?就像这篇文章中所说的那样。https://dev59.com/sHVC5IYBdhLWcg3wliKe。我相信phpass使用BCrypt。 - user2707535
@user2707535 - 我认为你没有理解答案。我可以获取任何哈希算法的输出,然后只需在密码框中键入它。你怎么知道它来自哪里? - Álvaro González
我认为你的逻辑有些混乱。你能解释一下整体情况吗?我无法想象出需要检查给定字符串是否为哈希的情况。 - Yaroslav

0

正如其他人所说,哈希是字符串,尽管(在某些条件下)您可以说md5或sha1始终是n个字符,但不能保证给定的字符串是哈希。

如果您现在想要比较用户提供的密码与保存在数据库中的哈希值,则可以从数据库中获取保存的哈希值,然后使用创建保存的哈希值时使用的相同函数对提供的字符串进行哈希处理,并确保它们相等并进行身份验证。


1
好的,谢谢。我本来希望有一些东西可以将哈希密码与字符串区分开来,但我想这并没有太多意义。 - user2707535

0

我不太确定你在尝试做什么,但我认为你在检查密码是否已经被散列。

如果你使用任何函数/库将其散列,则可以在该函数中检查哈希是否成功完成。

除此之外,你无法识别一个字符串是否已经被散列,因为它只是一个字符串。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接