2013-06-20 68 views
0

基本上我有一個遊戲服務器,其中有密碼hash作爲sha1,另一個作爲md5用於新用戶註冊帳戶。我決定堅持使用sha1,但是我希望能夠讓我的用戶更改他們的密碼,這些密碼將從md5創建到sha1。md5到sha1密碼hash更改

我已經得到了我已經寫好的下面的代碼,但它似乎沒有工作。

基本上,我希望當他們更改密碼時,它會用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> 

它要求在用戶表中將password列下的密碼更改爲sha1。用戶表中所有當前密碼均爲md5,需要轉換爲sha1。

對不起,如果這沒有意義。

+2

出於好奇,爲什麼不SHA SHA MD5的密碼? –

+0

另外,你看到[這個問題](http://stackoverflow.com/questions/16863775/most-efficient-way-to-change-the-hash-type-of-a-password-md5-to-sha1 ?RQ = 1)? –

+0

我對密碼哈希不熟悉。我有1,000多個註冊用戶,所有用戶都需要將MD5密碼切換到SHA1,以便他們可以成功登錄。 – user2506542

回答

0

正如我的評論中所解釋的那樣,爲了讓用戶儘可能順利地進行密碼存儲轉換,您希望做的是將所有人的密碼與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不適合散列密碼,特別是如果它是用恆定的鹽醃製的話。它速度太快,容易暴力(2013年,3 Giga hashes per second與通用硬件)。這就是爲什麼人們應該使用像BCrypt這樣的慢速密鑰派生函數。如果您努力遷移散列,那麼最好直接切換到BCrypt。

通常切換到更好散列算法的方法是等到用戶下一次登錄(與你的例子不同,用戶不需要更改密碼)。然後,您採取以下步驟:

  1. 首先嚐試使用新算法驗證輸入的密碼。然後,新密碼和已經轉換的密碼不再需要更長的時間進行驗證。
  2. 如果不匹配,請將其與舊的散列算法進行比較。
  3. 如果舊的散列值匹配,那麼您可以計算並存儲新的散列值,因爲您知道密碼。

該系統可以擴展到多個遷移。只要確保首先檢查最新的算法,然後再檢查較舊的算法。然後,只有在下次用戶登錄時,登錄纔會花費更長時間,並且新用戶不會受到向後兼容性問題的影響。

這留下了如何使用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個字符,存儲這樣的哈希值。