簡體   English   中英

PHP 忘記密碼 Function

[英]PHP Forgot Password Function

我有一個小型社區網站,我需要實現某種忘記密碼 function。 我目前將密碼存儲在數據庫中,用MD5加密。

是否可以對“解密”進行排序並通過 email 將其發送給用戶,還是我需要一個密碼重置頁面?

MD5 散列密碼不可逆。 (MD5 是散列,而不是真正的加密,所以有一個細微的差別)。 的,您肯定希望提供密碼“重置”過程(而不僅僅是 email 密碼)。

為您提供安全密碼重置的高級工作流程...

  1. 當用戶要求重置密碼時,讓他們輸入他們的 email 地址
  2. 不要指出 email 地址是否有效(只需告訴他們發送了 email 即可)。 這是有爭議的,因為它降低了可用性(即我不知道我注冊了哪個 email),但它為試圖收集有關哪些電子郵件實際在您的網站上注冊的信息的人提供的信息較少。
  3. 生成一個令牌(可能是 hash 一個帶鹽的時間戳)並將其存儲到數據庫中的用戶記錄中。
  4. 向用戶發送 email 以及指向您的http重置頁面的鏈接(URL 中的令牌和 email 地址)。
  5. 使用令牌和 email 地址來驗證用戶。
  6. 讓他們選擇一個新密碼,替換舊密碼。
  7. 此外,最好在特定時間范圍(通常是 24 小時)后使這些令牌過期。
  8. 可選地,記錄發生了多少“忘記”嘗試,如果人們請求大量電子郵件,則可能實現更復雜的功能。
  9. 或者,記錄(在單獨的表中)請求重置的個人的 IP 地址。 從 IP 增加一個計數。 如果它超過了,比如說,10...忽略他們未來的請求。

為了讓您更詳細地了解哈希...

當您在 PHP 中使用 md5() function hash 密碼之類的值時,無論您在哪個服務器上運行該密碼,最終值都將是相同的。 (所以我們可以立即看到散列和加密之間的一個區別......不涉及私鑰/公鑰)。

所以在這里你會看到人們提到彩虹表的漏洞。 彩虹表的一個非常基本的解釋是......你 md5() hash 一堆字典單詞(弱密碼),以便獲得它們的 md5() 散列值。 將它們放在數據庫表(彩虹表)中。

現在,如果您破壞了 web 站點的數據庫,您可以針對您的彩虹表運行用戶的散列密碼,以(本質上)將 hash “反轉”回密碼。 (您並沒有真正“反轉” hash ......但你明白了)。

這就是“加鹽”密碼的最佳做法。 這意味着(再次,這里非常基本的想法)你 append 在你 hash之前給用戶的密碼一個隨機值。 現在,當彩虹表針對您的數據庫運行時,它並不那么容易“反轉”,因為“密碼”的 md5() hash 與“密碼384746”不同。

這是一個很好的 SO Q/A 應該會有所幫助。 保護 hash 和鹽用於 PHP 密碼

根據這篇文章The distinct guide to forms based website authentication ,對於第 3 步和第 4 步,我不確定您是否應該發送您存儲的相同令牌。

我想您必須發送令牌,然后發送 hash 並將哈希令牌存儲在數據庫中。 否則,如果您的數據庫遭到破壞,則可以訪問重置密碼頁面。

總結一下:

$token = md5(microtime (TRUE)*100000);
$tokenToSendInMail = $token;
$tokenToStoreInDB = hash($token);

其中 hash 是散列算法。

不,MD5 是不可逆的。 散列密碼的目的是使訪問您的數據庫的攻擊者無法訪問每個人的密碼。

也就是說,MD5(尤其是未加鹽的 MD5)通常可以使用彩虹表進行攻擊。 為了安全起見,最好使用bcrypt

正如 Marcus Reed 所說,在 2015/2016 年,如果您的 PHP 版本 >=5.5,請不要使用 MD5,password_hash() 和 password_verify() 為您的密碼提供簡單安全的散列,並能夠提供成本並自動加鹽hash。

我目前沒有投票或評論的能力,這就是我提供明確聲明以避免混淆的原因。

您無法解密密碼,甚至不應該考慮通過明文向用戶發送密碼。 (這是讓我永遠不再使用網站的#1 方法;這是一個巨大的安全漏洞。)提供一個密碼重置頁面,該頁面由包含時間相關密鑰的鏈接觸發,該密鑰發送到用戶的密碼恢復 email ; 這就是當前密碼恢復技術中的 state。

你最好的辦法是要求人們在注冊時提交他們的 email 地址。 然后,如果他們忘記了,有一個忘記密碼鏈接,該鏈接使用一個隨機值重置他們的密碼,該值通過電子郵件發送給他們,這樣他們就可以獲得訪問權限,然后將他們的密碼改回更容易記住的東西。 這樣您就不需要損害安全性。 你可以有一個鏈接,他們只需要提交他們的用戶名,但為了更好的安全性,你應該有一個問題和答案或令人難忘的單詞。

使用 php 內置的 password_verify 和 password_hash。

MD5 旨在成為單向 hash。 您需要讓他們重置密碼。

編寫一個接受 md5 和 email 地址作為獲取參數的頁面,並在數據庫中查找 email 和 md5'd 密碼。 按照 Jared Cobb 的說明,這應該會讓你走上正確的道路。 我也添加了一些示例

例如 url 發送http://yourdomain.com/resetpassword.php?code=md5codesentviaemail

 $code = isset($_GET['code']) ? $_GET['code'] : '';
    $email = isset($_GET['email']) ? $_GET['email'] : '';
$checkPw = '';

    if(empty($code) || empty($email))
    {
     die();
    }
    $sqlQuery = 'SELECT * FROM users WHERE email = "'.$email.'";
//remember to check for sql injections
    //then get the results as an array, i use a database class eg $user

    if(!empty($user['password']))
    {
     $checkPw = md5($user['password']);
    }else
    {
     die();
    }

    if($checkPw !== $code)
    {
     die();
    }else
    {
    //display form for user to change password
    }

這應該足以讓您知道用戶是有效用戶並更改他的密碼

不,你不能解密它。 這就是整個想法。

您需要向他們發送臨時密碼並讓他們重置密碼。

您需要執行密碼重置頁面。 PHP 中無法解密 MD5。

MD5是單向 function。 你不能解密它。 所以你需要有一個密碼重置頁面。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM