2015-01-08 77 views
0

我使用這個PHP腳本來存儲用戶名和密碼,我的MySQL數據庫:存儲密碼,使用SHA2,mcrypt_create_iv,鹽和MD5

$nombre = $_POST['username']; 
$password = $_POST['password']; 
$stringpass = md5($password . 'AAA'); 

$size = mcrypt_get_iv_size(MCRYPT_CAST_256, MCRYPT_MODE_CFB); 
$salt = mcrypt_create_iv($size, MCRYPT_RAND); 
mysqli->query("INSERT INTO users(username,salt,password) VALUES ('$nombre','$salt',SHA2(CONCAT('$salt','$stringpass'), 512))")) 

記錄在MySQL是正確創建。但是,當我嘗試登錄時,此腳本無法識別我的密碼:

$nombre = $_POST['username']; 
$password = $_POST['password']; 
$stringpass = md5($password . 'AAA'); 
$resultado = $mysqli->query("select * from users where username='$nombre' and password = SHA2(CONCAT(salt,'$stringpass'), 512)") 

這不會爲我返回任何結果。有什麼想法可以失蹤?也許是鹽田的參考,但不知道如何做到這一點。

讓我明確一點,該代碼不適用於任何生產環境。它適用於學校項目,僅用於設計簡單用戶身份驗證腳本的演示。這就是說,我真的很想知道這段代碼中有什麼可能是錯誤的,或者我需要在PHP/MySQL環境中檢查什麼特定的配置。

+1

**警告**:編寫自己的訪問控制層並不容易,而且有很多機會讓它嚴重錯誤。在這個簡短的例子中,你有一些危險的[SQL注入漏洞](http://bobby-tables.com/)來自於[正確轉義](http://bobby-tables.com/php) 。請不要在[Laravel](http://laravel.com/)等任何現代開發框架(http://codegeekz.com/best-php-frameworks-for-developers/)上編寫自己的認證系統,內置了強大的[認證系統](http://laravel.com/docs/security)。 – tadman

+3

您迫切需要閱讀[密碼散列](http://www.phptherightway.com/#password_hashing)最佳實踐。 – tadman

+0

可能是一個字符集問題。你正在將原始的二進制垃圾填充到這些字段中。這些字節偶然可能會被解釋爲特定字符集中的「特殊」字符,並且會被破壞進入或離開數據庫。你應該使用binary/varbinary字段來處理這類事情。 –

回答

4

我不確定確切的問題是什麼,但這可能有所幫助。

Php提供了一個更簡單的替代方法,可以自動生成salt和hash - password_hash()函數。你只需要做password_hash($password, PASSWORD_BCRYPT);,它會生成一個salt,用它來散列密碼,然後把salt追加到hash的前面。

這裏是文檔頁面。

http://php.net/manual/en/function.password-hash.php

+0

新PHP密碼散列API至少需要PHP 5.5。 –

0

生成的鹽是一個二進制字符串,所以你不能僅僅把它插入到一個SQL語句,你將不得不使用準備好的語句或逃逸。

無論這個問題,這不是一個安全的方式來存儲密碼。 SHA- *算法不適合散列密碼,而應該使用具有成本因子(BCrypt,PBKDF2)的慢速算法。

PHP現在提供了一種更簡單的方法來生成安全的密碼哈希函數,其功能爲password_hash()(早期版本也可以使用compatibility pack)。 salt成爲哈希值的一部分,因此不需要將其分別存儲在數據庫中。

// 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);