【问题标题】:Add password_hash() to php with txt flatfile database使用文本平面文件数据库将 password_hash() 添加到 php
【发布时间】:2015-12-14 03:09:12
【问题描述】:

我想了解password_hash() 函数的工作原理。

我有这个超级简化的 php 登录(完全不安全,只是为了学习而设计的),我选择了四个密码。

<?php

$data = file_get_contents('pass.txt');

if($_POST['pass']) {
    $line = explode("\n", $data);
    for($i = 0; $i<count($line); $i++) {
        $item = explode("#", $line[$i]);
        if($_POST['pass'] == $item[0]) {
            echo "Welcome! You're logged in!";
        }
    }
}

else { echo '<form method="POST" action="">
            <input type="password" name="pass">
            <input type="submit">
            <form>';
}

?>

还有这个pass.txt,保存密码的地方(.txt 平面文件数据库):

passone
passtwo
passthree
passfour

是否可以在我的代码中添加 password_hash() 函数?

我猜php应该能够为此重写数据库,因为这个函数会在你每次登录时重写密码。

谢谢你们XXX

【问题讨论】:

  • 您的确切疑问是什么?如果您散列密码,您将存储诸如“$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a”之类的东西,而不是“passone”。大致就是这样。
  • 是的,但不是每次登录都要更改吗? php应该重写txt文件吗?我不知道怎么写:'(
  • 使用可预测的盐,例如用户名之类的。然后哈希将保持一致,这将允许您进行比较。
  • @DevDonkey 不!不不不。盐必须是随机的。 password_hash 创建一个随机盐。不要颠覆这一点,它缺少盐的意义。你只需要使用password_verify 而不是==
  • @deceze 啊哈,我不知道有这样的魔法存在!酷:)

标签: php file text flat-file php-password-hash


【解决方案1】:

是的。

哦,你应该使用 isset,否则你可能会得到 PHP 错误。你应该打破;找到正确密码后,剩下的就是浪费cpu了。

首先创建您的 pass.txt:

<?php
$passes=array(
'passone','passtwo','passthree'
);
foreach($passes as &$pass){
$pass=password_hash($pass,PASSWORD_DEFAULT);
}
file_put_contents("pass.txt",implode("\n",$passes));

那就点赞

<?php

$data = file_get_contents('pass.txt');

if(array_key_exists('pass',$_POST)){
    $lines = explode("\n", $data);
    for($i = 0; $i<count($lines); $i++) {
        if(password_verify($_POST['pass'],$lines[$i])) {
            echo "Welcome! You're logged in!";
            break;
        }
    }
}

else { echo '<form method="POST" action="">
            <input type="password" name="pass">
            <input type="submit">
            <form>';
}
  • 虽然是警告词。就我个人而言,我不喜欢 password_hash,因为它不容易与用其他语言编写的应用程序集成(在我的场景中是 c++),哈希结构没有明确定义(据我所知),缺少阅读 php 解释器的源代码代码..

【讨论】:

  • 看起来很不错,但是密码应该写在php文件中吗? (上面代码的第 3 行)
  • 从哪里获取密码取决于您。从文本文件、数据库等中获取密码。在这里,我只是将它们硬编码在一个 php 文件中,是的。继续,使用 $passes=file("unencrypted_pa​​sswords.txt",FILE_IGNORE_NEW_LINES); ^^
  • 我正在尝试您的代码。这很棒。创建密码的代码中的一切是否正确?它在数据库中写入 UNENCRYPTED 密码。它不应该编写散列代码并不断重写它们吗?
  • wups,我在代码中发现了一个错字,“foreach($passess as &$pass)”应该是“foreach($passes as &$pass)”.. 但密码应该在数据库中加密/散列,是的..我自己尝试了代码,所有内容都在 pass.txt 中散列,没有明文密码..
  • 我会给你打勾,这是一个非常好的解决方案。无论如何,一旦它们在数据库中被写入,应该有一种方法可以摆脱 php 中的普通密码。不应该吗?
【解决方案2】:
  1. 为您的每个密码执行echo password_hash('passone'),将生成的长 gobbledygook 字符串存储在您的文本文件中。
  2. 而不是if ($_POST['pass'] == $item[0])
    你做if (password_verify($_POST['pass'], $item[0]))

也就是说,您在明文密码和文本文件中的散列密码上使用password_verifypassword_hash 在哈希过程中创建一个随机盐。 此随机盐是它返回的 gobbledygook 字符串的一部分!您需要在比较期间重复使用该随机盐。 password_verify 会为您解决这些问题。

这就是我们所需要的。

【讨论】:

  • 谢谢,您似乎理解我的意思,但是每次登录时存储的密码都会更改,并且根据您的方法,它不会这样做,因为它不会修改平面文件数据库。 (不知道有没有解释清楚)XXX
  • 查看我的更新。您只需对初始密码散列一次,然后使用password_verify。你不需要不断改变任何东西。
  • 查看stackoverflow.com/a/16736254/476了解底层机制的解释。
  • 感谢四位您的关注!你的回答绝对很棒,但另一个最适合我的意图。也许我没有正确表达这个问题。我也赞成您的回答,因为我认为它也可能有用。再次感谢xxx
猜你喜欢
  • 2015-07-29
  • 1970-01-01
  • 2011-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-12
  • 1970-01-01
相关资源
最近更新 更多