2011-04-22 141 views
0

我正嘗試使用mcrypt在我的數據庫上存儲密碼。首先,它起作用,但只有一些時間。使用mcrypt,PHP和MySQL進行加密

這裏是我的加密代碼:

//Encryption/Decryption key 
    $key = $username.$username.$username.$username.$username; 
    //Encryption Algorithm 
    $cipher_alg = MCRYPT_RIJNDAEL_256; 

    $iv = mcrypt_create_iv(mcrypt_get_iv_size($cipher_alg, MCRYPT_MODE_ECB), MCRYPT_RAND); 
    $password = mcrypt_encrypt($cipher_alg, $key, $pass1, MCRYPT_MODE_CBC, $iv); 

這則上傳$的用戶名,在$ IV和$密碼到MySQL數據庫。

這裏是我的解密代碼:

//Encryption/Decryption key 
    $key = $username.$username.$username.$username.$username; 

    //Encryption Algorithm 
    $cipher_alg = MCRYPT_RIJNDAEL_256; 

    $dbpass = mcrypt_decrypt($cipher_alg, $key, $encpass, MCRYPT_MODE_CBC, $random); 
    $dbpass = trim($dbpass); // Trim the fat 

的$用戶名,$ IV,和$ encpass(加密的密碼)從數據庫中檢索和密鑰使用的用戶名重建。

這工作,但只有時。我無法弄清楚爲什麼。我唯一的假設是數據庫不能接受加密產生的一些字符,例如引號。

任何幫助將不勝感激!

+0

請告訴我們您使用的數據插入到數據庫中的代碼,以及用於檢索它的代碼。我們還需要知道表格的結構。另外,你爲什麼在ECB模式下獲取IV,但在CBC模式下進行加密? – Charles 2011-04-22 17:05:20

+0

據我所知算法取決於密鑰和IV大小和用戶名是不可接受的既不是通過/也不是關鍵..你不能依靠用戶輸入! – 2013-02-06 22:25:34

回答

0

如果要存儲用戶的數據庫中的密碼,你應該使用單向散列

這裏只是一個非常簡約的例子

$username = $_POST['username']; 
$password = $_POST['password']; 
$salt  = 'Some Salt'; 

$result = mysql_query("SELECT username, password 
         WHERE username = '".mysql_real_escape_string($username)."' 
         AND password = '".mysql_real_escape_string(sha1($password . $salt))."' 
         LIMIT 1"); 

if(mysql_num_rows($result)) { 
// we have a match 
} 
else { 
// no match 
} 

你將不得不將用戶的密碼與在我的例子中使用sha1附加鹽。請記住,這只是將用戶密碼存儲在數據庫中的建議。

+0

這個頁面已經有幾年了,但它仍然提供了一些很好的見解http://www.ibm.com/developerworks/opensource/library/os-php-encrypt/ – Brett 2011-04-22 17:12:42

+0

那麼我想最終都是這樣做的。我打算首先用鹽對它進行散列,然後進行加密。我背後的想法是,如果我的數據庫被盜了,他們將擁有$ iv和$密碼,如果他們擁有我的PHP,他們將擁有$ key和$ salt,但沒有他們兩個都無能爲力。這是正確的嗎? 哦,無論如何,如果我不能弄清楚爲什麼我的密碼/ $ iv可能沒有正確存儲,那我就不好。我應該使用addslash嗎? – Connor 2011-04-22 17:37:20

+1

mysql_real_escape_string是轉義字符串的正確方法。至於在數據庫中存儲密碼,單向散列法絕對是一種方法。我會發布一些示例代碼,可以幫助您 – Brett 2011-04-22 17:48:09

1
$salt = time(); // I would use something other than time(), something more random 

// store it in the db and redirect user 
connect(); 
$query = mysql_query("INSERT INTO user VALUES 
         ('".mysql_real_escape_string($username)."', 
         '".mysql_real_escape_string(sha1($password . $salt))."', 
         '".mysql_real_escape_string($salt)."') "); 

// returning user 
$username = $_POST['username']; 
$password = $_POST['password']; 

// retrieve stored password 
connect(); 
$result = mysql_query("SELECT * FROM user WHERE username = '".mysql_real_escape_string($username)."' "); 
$row = mysql_fetch_assoc($result); 
if (!$result) { 
// user doesn't exist 
} 
$storedPassword = $row['password']; 
$salt = $row['salt']; 

$hashedPassword = sha1($password . $salt); 

if ($storedPassword != $hashedPassword) { 
// exit 
} 
else { 
// redirect user 
} 

我並不是聲稱這是最安全的,它只是一個用鹽進行單向哈希的小例子。

+0

有大量的文檔和幫助那裏有更多的安全經驗的人。你會在stackoverflow中發現一些很好的提示。 – Brett 2011-04-22 18:09:20

+0

我在這裏發現了一個很好的哈希指南:http://elbertf.com/2010/01/store-passwords-safely-with-php-and-mysql/ 但是現在忘記密碼,爲什麼我的加密工作不正常? – Connor 2011-04-22 19:05:04

1

您可以嘗試下面的代碼進行雙向加密。您可以根據您的要求添加密碼鹽。

$key = 'ecryptionkey'; 
$string = 'password'; 

$encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $string, MCRYPT_MODE_CBC, md5(md5($key)))); 
$decrypted = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($encrypted), MCRYPT_MODE_CBC, md5(md5($key))), "\0"); 

var_dump($encrypted); 
var_dump($decrypted); 

我從下面的URL得到了這段代碼,我在我的應用程序中使用它。

https://stackoverflow.com/a/9262137/1724762