2011-11-10 89 views
0

一個簡單的註冊和登錄頁面的網站。我正試圖加密密碼+醃製。這就是我所做的,但我不確定它是否正確。PHP crypt密碼

這是在註冊頁面會發生什麼:

$blowfish = '$2a$10$'; 
$salt = '8dF$d_3'; 
$hashedPass = crypt($password,$blowfish . $salt); 

在數據庫中,密碼爲 「RAYray99」 存儲爲「$ 2A $ 10 $ 8dF $ D_3 $$$$$$$$$$ $$$$。wxsfa7X.nkcGqldJ9fujdd8eY.H85uC」


在登錄頁面,我被困在如何檢查與數據庫中的密碼輸入的密碼。

這是登錄電子PHP腳本,驗證用戶:

mysql_connect("$db_host", "$db_username", "$db_pass") or die(mysql_error()); 
//select the database or return error message 
mysql_select_db("$db_name") or die("database does not exist"); 

$email = stripslashes($_POST['email']); 
$email = strip_tags($email); 
$email = mysql_real_escape_string($email); 
$password = ereg_replace("[^A-Za-z0-9]", "", $_POST['password']); // filter everything but numbers and letters 
$password = crypt($password); 

$sql = mysql_query("SELECT * FROM members WHERE email='$email' AND password='$password' AND activateemail='1'"); 
$login_check = mysql_num_rows($sql); 
if($login_check > 0){ 
while($row = mysql_fetch_array($sql)){ 
    // Get member ID into a session variable 
    $id = $row["id"]; 
    session_register('id'); 
    $_SESSION['id'] = $id; 
    // Get member username into a session variable 
    $username = $row["username"]; 
    session_register('username'); 
    $_SESSION['username'] = $username; 
    // Update last_log_date field for this member now 
    mysql_query("UPDATE members SET lastlogin=now() WHERE id='$id'"); 
    // Print success message here if all went well then exit the script 
    header("location: account.php"); 
    exit(); 
} // close while 

} else { 
// Print login failure message to the user and link them back to your login page 
    print '<br /><br /><font color="#FF0000">ERROR TRY AGAIN </font><br />; 
    exit(); 
} 

我的問題是如何將我驗證的登錄密碼時應數據庫的登錄頁面上輸入與1。

謝謝 雷

+0

不要加密密碼......而不是加密!擺脫你的''標籤。這些已被棄用多年!最後,根據RFC,您的'Location:'標頭必須是絕對URL。是的,相對路徑通常會起作用,但當它不行時,你不想陷入麻煩。另外,您還需要進行SQL注入。 **對於SQL注入,剝離斜槓不是一種適當的保護措施!通過準備好的查詢學習PDO。 – Brad

+0

爲什麼你加密密碼而不是散列(解密幾乎不可能)呢? 密碼的過濾使其更加不安全!順便說一句['ereg_replace()'](http://php.net/manual/function.ereg-replace.php)已被棄用。 – ComFreek

+0

與您的問題無關的提示,您不需要將變量放在引號中就可以使用它們。例如,你的connect調用可以是'mysql_connect($ db_host,$ db_username,$ db_pass)' – jprofitt

回答

0

我使用的是映射爲我的SQL查詢(doctrine2)。

我的密碼都在我的分貝

public function setPassword($password) { 
    $this->_password = self::encodePassword ($password); 
    return $this; 
} 
/** 
* This function encodes the password to md5 after adding a salt 
* @param string $password 
*/ 
public static function encodePassword($password) { 
    $salt = 'dsa7893ujlksdsagkz27392kjsjaldksju928ikljda27'; 
    return md5 ($password . $salt); 
} 

我的登錄看起來像這樣保存的MD5 +鹽...

/** 
* Executes an authentication try 
* 
* @throws Zend_Auth_Adapter_Exception if the authentication failed 
* @return Zend_Auth_Result 
*/ 
public function authenticate() 
{ 
     //check if login is correct 
     try{ 
       $user = $this->_em->getRepository('App_Model_User') 
        ->findOneBy(
         array(
          '_email' => $this->_login, 
          '_password' => App_Model_User::encodePassword($this->_password) 
         ) 
       ); 
     }catch(Exception $e){ 
       throw new Zend_Auth_Adapter_Exception('authentication failed', 0, $e);    
     } 

.............

+1

我會推薦用'sha256'或者'sha512'來代替'md5'。 – ComFreek

+0

這些算法的長度是多少? –

+0

這裏是一個列表:http://php.net/manual/en/function.hash.php#104987 – ComFreek

-1

正如@布拉德指出,它會更簡單(並在一定程度上更安全​​)散列密碼,而不是加密它們。

MySQL無論如何都支持MD5和SHA1哈希。

一個的去這條路線的優點是你可以做兩種:

$pass = md5($salt . $pass); 
$SQL = "SELECT * FROM users WHERE username = '$user' AND pass = '$pass';"; 

或者直接在數據庫

$SQL = "SELECT * FROM users WHERE username = '$user' AND pass = MD5('{$salt}{$pass}')"; 
+1

PHP's'crypt()'函數不是雙向加密。該名稱完全是誤導性的(在PHP基礎庫中添加另一點)。 PHP文檔甚至在函數的頁面上說「crypt - 單向字符串哈希」。 – Tesserex

+0

你是完全正確的,我與mcrypt函數混淆,並沒有驗證 – rantsh

1

要驗證密碼,你應該散列進入一個完全當你將它存放在第一位時,也是這樣。

我看到你有什麼問題。首先,根據PHP文檔,crypt()的河豚字符串指定在您的$2a$10$應該是來自./0-9A-Za-z字母表的22個字符的字符串之後。你的鹽沒有遵循,所以哈希函數可能完全失敗(雖然我不確定)。

此外,你的鹽不應該是你的應用程序中的常量,它應該是每個用戶都獨一無二的,並且存儲在數據庫中以及散列的密碼。

最後,在散列之前,您不應該對密碼進行這些轉換。分解一個以明文密碼爲輸入的函數,並輸出散列密碼。在存儲密碼時以及嘗試驗證登錄時使用此功能。這樣你就可以確定它應該匹配數據庫。

0
$password = $_POST['password']; 
$str = "$2a$10$8dF$d_3$$$$$$$$$$$$$$.wxsfa7X.nkcGqldJ9fujdd8eY.H85uC"; 

if (preg_match('/^(.{7})(.{7})(.+?)$/', $str, $m)) 
{ 
    $blowfish = $m[1]; 
    $salt = $m[2]; 
    $hashedPass = $m[3]; 
    $validHashedPass = crypt($password,$blowfish.$salt); 

    if ($validHashedPass == $hashedPass) 
    { 
      good pass 
    } 
    else 
    { 
      wrong auth 
    } 
} 
0

我有一個類只爲這種情況下內置的類。它使用sha1()散列函數和PDO預準備語句來防止SQL注入。我會盡力找到它並在這裏發佈,但如果我不這樣做,這是我對你的建議:

  • 使用哈希函數,而不是一個加密函數。
  • 請勿使用mysql_*,因爲它不支持預準備語句。使用PDO或非常簡單,mysqli
+0

謝謝,如果你找到它,請發佈它。乾杯 –