基本加密登录验证


Basic crypt login verification

所以我有一个基本的数据库,密码只使用基本的crypt()函数进行哈希处理(不是很好的做法,对吧?

我现在正在尝试制作登录页面。这是我的基本代码。

if (isset($_POST['username'])
 && isset($_POST['input_password'])
 && !empty($_POST['username'])
 && !empty($_POST['input_password'])) {
    $username = trim($_POST['username']);
    $input_password = trim($_POST['input_password']);
    $sql = "SELECT username, password FROM registration WHERE username=? && password=?";

我真的很挣扎。我可以用基本文本作为密码进行登录,可以让它工作。但是哈希固有的验证方面正在抛弃我。

我知道我需要做一些类似于:

if(crypt($input_password, $db_pass)==$db_pass) //plus the username stuff
    echo 'Logged in!';
}

我是否需要先执行单独的 SELECT 查询才能从输入的用户名中获取密码?然后通过crypt用数据库密码验证输入的密码?

所以喜欢:

$sql = "SELECT username, password FROM registration WHERE username=?";
$stmt = $db -> prepare($sql);
$stmt -> bind_param('s', $username);
$stmt -> execute();
$stmt -> bind_result($db_user, $db_pass);
$stmt -> fetch();
  if(crypt($input_password, $db_pass)==$db_pass) //plus the username stuff
        echo 'Logged in!';
    }else{
        echo 'Not logged in';
  }

这是正确的方式吗?仅通过用户名直接从数据库中获取密码似乎不是很安全。但我想不出任何其他方法。

注意:这不是为了实际用途,只是为了教育。

您不必检查if语句中的密码是否相同,SQL 查询就足够了。

查看检索到的行计数是否为>= 1 就足够了。

最佳做法是在数据库中保存密码的哈希版本,然后使用 SELECT 查询查找用户名和哈希密码是否与提供的凭据相同。

我的观点是,在查询中使用它们之前,您应该比使用 isset 和 !empty 更好地限定 POST。

更好的方法是为密码生成哈希,并在 SELECT 查询中使用哈希,然后比较用户名。

原因是这样你就把SQL注入排除在外了。出于同样的原因,我也要求在适用的情况下使用一个数值(例如最后 4 个,电话)用 intval($_POST['number']) 限定它。

我的首选哈希值是$hash = hash('ripemd320',$password);

我不知道它今天是否仍然适用,但在我研究哈希算法时,ripemd320 是从未被破解过的算法。

即便如此,我仍然检查输入值,看看他们是否发布了任何包含通常用于SQL注入的SQL的内容:

  $strike1 = preg_match_all('/'x2C/',$inputValue,$matches, PREG_SET_ORDER); 
  $strike2 = preg_match_all('/['x21-'x2F]|['x3A-'x40]|['x5B-'x60]|['x7B-'x7F]/',$inputValue,$matches, PREG_SET_ORDER);
  $strike3 =  preg_match_all('/COALESCE|0x|like|regex|mid|select|delete|drop|insert|do|call|replace|update|infile|lock|set|from|into|show|table|kill|reset/i',$inputValue,$matches, PREG_SET_ORDER);

请记住,我已经老了,并且已经这样做了很长时间。所以是的,我的代码可能使用折旧的 PHP。

我还关注蛮力攻击。
这段代码来自我的早期,可以改进。 但它有效。

      $sql = "SELECT `ip`,`TimeStamp`  FROM `access` WHERE `ip` LIKE '$ip'  AND `TimeStamp`  > CURRENT_TIMESTAMP order by `TimeStamp` ASC";
      $results = @mysql_query($sql);
      $rows = mysql_num_rows($results);
      if ($rows == 1) {
        $ipCount = 1;
        $timeCount = abs(strtotime($row[1]) - time());
        $timeMin = $time;
        $timeMax = $time;
      }
      $row = @mysql_fetch_array($results, MYSQL_NUM);
  if ($rowCount > 1) {
    $saveIP[$ipCount++] = $row[0];
    $saveTime[$timeCount++] = strtotime($row[1]);
    while ($row = mysql_fetch_array($results, MYSQL_NUM)) {
      $saveTime[$timeCount] = strtotime($row[1]);
      $time = $saveTime[$timeCount] - $saveTime[$timeCount - 1];
      if ($time > $timeMax){
         $timeMax = $time;
       }
      if ($time < $timeMin){
         $timeMin = $time;
       }
      $rowCount += $row[0];
      if ( !in_array($row[0],$saveIP)) {
         $saveIP[$ipCount++] = $row[0];
         $saveIP = $row[0];
         $ipCount++;
      }
    }     
  }

如果我发现不可接受的行为:

@mysql_query("INSERT INTO `_portal`.`Banned` (`ip`, `TimeStamp`,`Strikes`, `Attributes`) VALUES ('$ip', CURRENT_TIMESTAMP, $alert);");

特别是在共享服务器上,明智的做法是不要将mysql_connect()放在公共脚本中,如果服务器配置错误,而 PHP 作为 MIME 类型文本/纯文本提供,则不要将数据库名称和密码暴露在外。 并不少见。 在共享服务器上,我已经能够使用. Opps,不打算发布该代码。

为了连接,我使用类似
include('/home/user/secureStorage/P7gAv2fH4pU.php');

当对脚本的访问是管理性的时,我只允许从我的IP访问。

 if ((hash('ripemd320',$passcode) == '6732f3c024fe3c3c1ccd7dbe5d0fa7d4a53c516f800707bb86a9017c1e1646d9d4a2d7adc56a505d') && (substr($ip,0,11)  == '152.30.52.72' || $ip == '72.3.150.55' || $ip == '17.162.23.21' )){
      $admin = true;
    }