【问题标题】:md5 to sha1 password hash changingmd5 到 sha1 密码哈希更改
【发布时间】:2013-06-17 18:50:32
【问题描述】:

基本上,当新用户注册帐户时,我有一个游戏服务器,其中密码哈希为 sha1,另一个为 md5。我决定坚持使用 sha1,但是我希望我的用户能够更改他们的密码,这会将他们从 md5 创建为 sha1。

我已经编写了以下代码,但它似乎不起作用。

基本上,我希望他们在更改密码时将 md5 替换为 sha1 哈希密码。

    <?php
if(isSet($_POST['submit']))
{
$changePW = true;
}
?>

<?php
public function hashed($password)

 {

  return sha1($password . "xCg532%@%gdvf^5DGaa6&*rFTfg^FD4\$OIFThrR_gh(ugf*/");

 }
?>

<?php
if(isset($changePW))
{
    //host, username, password, dbName
    $con=mysqli_connect("localhost","root","password","dbName");

    $username = $_POST['username'];
    $password = $_POST['passwordOld'];
    $passwordNew1 = $_POST['passwordNew1'];
    $passwordNew2 = $_POST['passwordNew2'];

    $passwordHash = md5($password);

// Check connection
if (mysqli_connect_errno())
  {
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
  }

  $cmd = "SELECT COUNT(*) FROM users WHERE username = '" . $username . "' AND password = '" . $passwordHash . "'";
  $result = mysqli_query($con,$cmd);
  $row = mysqli_fetch_row($result);
  if($row[0] == 1)
  {
      if($passwordNew1 == $passwordNew2)
      {
          $newHash = hashed($passwordNew1);
          $cmd = "UPDATE users SET password = '$newHash' WHERE username = '$username'";
          mysqli_query($con,$cmd);
      }
      else{
          $passwordMatch = true;
      }
  }
 else {
      $detailsError = true;
  }

  //$hash = md5($password);
  //mysqli_query($con,"INSERT INTO tutorials_tbl (name, hash) VALUES ('" . $username . "','" . $hash . "')");

mysqli_close($con);
}
?>

<head>
    <style type="text/css">
        .lblLabel{
            width:165px;
            display: inline-block;
        }
    </style>
</head>

<form name="login" method="post" action="change.php">

<fieldset style="width:350px;"><legend>Change Password Form</legend>

<label class="lblLabel">Username</label><input id="name" type="text" name="username" value=""><br />

<label class="lblLabel">Old Password</label><input type="password" name="passwordOld"><br />
<?php
    if(isset($detailsError))
    { ?>
<span style="color: #F00; font-weight: bold;">Username or Password Incorrect</span>
    <?php }
    ?>
<label class="lblLabel">New Password</label><input type="password" name="passwordNew1"><br />

<label class="lblLabel">Repeated New Password</label><input type="password" name="passwordNew2"><br />
<?php
    if(isset($passwordMatch))
    { ?>
<span style="color: #F00; font-weight: bold;">Password's do not match</span>
    <?php }
    ?>
<label class="lblLabel">&nbsp;</label><input id="submit" type="submit" name="submit" value="Change Password"><br />
</fieldset>

</form>

它正在调用将用户表中密码列下的密码更改为sha1。 users表中所有当前密码都是md5,需要转换成sha1。

对不起,如果这没有意义。

【问题讨论】:

  • 出于好奇,为什么不 SHA MD5 的密码?
  • 另外,你看到this question了吗?
  • 我不熟悉密码哈希。我有1000+注册用户,都是MD5密码,需要换成SHA1才能登录成功。
  • 基本上,您要做的只是一次,遍历每个用户并对他们的密码进行 SHA 哈希处理。这将创建密码的 SHA 哈希。当您进行登录检查时,您将对给定密码进行 MD5 哈希处理,对结果进行 SHA 哈希处理,然后对照您的用户表进行检查。这对您来说是最少的初始工作,并且对您的用户来说是一个无缝过渡(他们不必更改密码,您不必维护他们的密码的两条记录等)
  • 您的密码字段在数据库中有多大?它可能太小,这会导致密码被截断,导致所有尝试验证数据库失败。

标签: hash md5 sha1


【解决方案1】:

正如我在评论中所解释的,为了让用户在密码存储中的转换尽可能顺利,您想要做的是将每个人的密码与 SHA1 进行哈希处理 同时将其保留为 MD5 哈希处理 .然后,在您的正常登录逻辑中,您将对密码进行 MD5 哈希处理,然后对其进行 SHA1 哈希处理。

顺便说一句,我会将 SHA2 用于哈希算法(同样快速、更安全等)

<?php
public function hashSpecial($password)
{
    return sha1($password . "xCg532%@%gdvf^5DGaa6&*rFTfg^FD4\$OIFThrR_gh(ugf*/");
}

public function hashForLogin($password)
{
    return sha1(md5($password) 
        . "xCg532%@%gdvf^5DGaa6&*rFTfg^FD4\$OIFThrR_gh(ugf*/");
}

public function hashAllPasswords()
{
    $con = mysqli_connect("localhost", "root", "password", "dbName");

    $query = 'SELECT username, password FROM users';
    if(mysqli_connect_errno() > 0)
    {
        echo 'Failed to connect to database.';
        break;
    }
    else
    {
        $result = mysqli_query($con, $query);
        while(($row = mysqli_fetch_row($result)) != null)
        {
            $query = 'UPDATE users SET password=\'' 
                 . hashSpecial($row['password']) . '\' WHERE username=\''
                 . $row['username'] . '\'';
            $r2 = mysqli_query($con, $query);
        }
    }
}
?>

【讨论】:

    【解决方案2】:

    每个密码存储系统都必须有切换到更好哈希算法的选项,您的问题不是一次性迁移问题。像 BCrypt 这样好的密码哈希算法有一个成本因素,有时您必须增加这个成本因素(因为更快的硬件),然后您需要与迁移所需的完全相同的过程。

    这导致了你最大的问题,SHA-1 不适合散列密码,特别是如果它是用恒定盐加盐的。它的速度太快了,很容易暴力破解(3 Giga hashes per second 与 2013 年的通用硬件)。这就是为什么人们应该使用像 BCrypt 这样的慢速密钥派生函数。如果你努力迁移你的哈希值,那么最好直接切换到 BCrypt。

    切换到更好的哈希算法的通常方法是等到用户下次登录(与您的示例相反,用户不需要更改密码) .然后你采取以下步骤:

    1. 首先尝试使用新算法验证输入的密码。届时,新密码和已转换的密码将不再需要验证。
    2. 如果不匹配,则与旧的哈希算法进行比较。
    3. 如果旧的哈希值匹配,那么你可以计算并存储新的哈希,因为你知道密码。

    此系统可以扩展到多个迁移。只要确保您首先检查最新算法,然后检查旧算法。那么只有在用户下次登录时,登录时间才会更长,并且新用户不会受到向后兼容性问题的影响。

    这就留下了如何使用 BCrypt 的问题。 PHP 5.5 将拥有自己的函数password_hash() 和 password_verify() 准备就绪。我建议使用这个优秀的 api,或者它是 compatibility pack 用于早期的 PHP 版本。用法很简单:

    // Hash a new password for storing in the database.
    // The function automatically generates a cryptographically safe salt.
    $hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
    
    // Check if the hash of the entered login password, matches the stored hash.
    // The salt and the cost factor will be extracted from $existingHashFromDb.
    $isPasswordCorrect = password_verify($password, $existingHashFromDb);
    

    ➽ 请记住,您需要一个长度为 60 个字符的数据库字段来存储此类哈希值。

    【讨论】:

      猜你喜欢
      • 2013-05-27
      • 2013-03-15
      • 2011-08-16
      • 2014-02-07
      • 1970-01-01
      • 2011-04-30
      • 2011-02-11
      • 2020-09-16
      • 2011-06-28
      相关资源
      最近更新 更多