基本上我有一个游戏服务器,其中密码哈希为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"> </label><input id="submit" type="submit" name="submit" value="Change Password"><br />
</fieldset>
</form>
它要求在users表中将密码列下的密码更改为sha1。 users表中的所有当前密码都是md5,需要转换为sha1。
很抱歉,如果这没有意义。
答案 0 :(得分:2)
每个密码存储系统都必须具有切换到更好的哈希算法的选项,您的问题不是一次性迁移问题。良好的密码哈希算法(如BCrypt)有一个成本因素,有时你必须增加这个成本因素(因为硬件速度更快),那么你需要完全相同的程序来进行迁移。
这导致了你最大的问题, SHA-1不适合散列密码,特别是如果它是用恒定盐加盐的话。它的速度太快,很容易暴力(2013年使用通用硬件3 Giga hashes per second)。这就是为什么人们应该使用像BCrypt这样的慢键派生函数。如果您努力迁移哈希值,那么最好直接切换到BCrypt。
切换到更好的哈希算法的常用方法是等到用户下次登录(与您的示例相反,用户不需要更改密码) 。然后你采取这个步骤:
此系统可以扩展到多个迁移。只需确保首先检查最新算法,然后检查旧算法。然后,登录将在用户下次登录时花费更长时间,新用户不会受到向后兼容性问题的影响。
这就留下了如何使用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);
}
}
}
?>