md5到sha1密码哈希更改

时间:2013-06-20 19:01:56

标签: hash md5 sha1

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

我已经编写了下面的代码,但似乎没有用。

基本上,我希望它在更改密码时用sha1哈希密码替换md5。

    <?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>

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

很抱歉,如果这没有意义。

2 个答案:

答案 0 :(得分:2)

每个密码存储系统都必须具有切换到更好的哈希算法的选项,您的问题不是一次性迁移问题。良好的密码哈希算法(如BCrypt)有一个成本因素,有时你必须增加这个成本因素(因为硬件速度更快),那么你需要完全相同的程序来进行迁移。

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

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

  1. 首先尝试使用新算法验证输入的密码。新密码和已转换的密码不会花费更长时间进行验证。
  2. 如果不匹配,请将其与旧的哈希算法进行比较。
  3. 如果旧的哈希值匹配,那么您可以计算并存储新哈希,因为您知道密码。
  4. 此系统可以扩展到多个迁移。只需确保首先检查最新算法,然后检查旧算法。然后,登录将在用户下次登录时花费更长时间,新用户不会受到向后兼容性问题的影响。

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

    // 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个字符的数据库字段来存储此类哈希值。

答案 1 :(得分:0)

正如我的评论中所解释的那样,为了让用户尽可能顺利地进行密码存储转换,你想要做的就是将所有人的密码与SHA1 进行哈希,同时保留MD5-hashed 。然后,在您的正常登录逻辑中,您将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);
        }
    }
}
?>
相关问题