2013-05-11 110 views
-1

我想加密密码以防止SQL注入和其他攻击,并且我在PHP中使用了加密函数,但我不知道如何使用它来加密密码。使用加密函数在mysql数据库中加密安全密码

我想要加密用户表中的每个密码,以便我可以连接到数据库并使用查询,但它不起作用。

任何人都可以帮助我吗?

ecnription.php

<?php 
require_once('include/connect.php'); 

if(isset($_SESSION['user_id'])) 
{ 
    $id= $_SESSION['user_id']; 


} 
$sql = mysql_query("SELECT password FROM user WHERE user_id= '$id'")or die(mysql_error()); 
while($row = mysql_fetch_array($sql)) 
{ 
    $enc_pass= $row['password']; 

} 

error_reporting(0); 

class Encryption 
{ 
    const CYPHER = MCRYPT_RIJNDAEL_256; 
    const MODE = MCRYPT_MODE_CBC; 
    const KEY = 'somesecretphrase'; 

    public function encrypt($plaintext) 
    { 
     $td = mcrypt_module_open(self::CYPHER, '', self::MODE, ''); 
     $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND); 
     mcrypt_generic_init($td, self::KEY, $iv); 
     $crypttext = mcrypt_generic($td, $plaintext); 
     mcrypt_generic_deinit($td); 
     return base64_encode($iv.$crypttext); 
    } 

    public function decrypt($crypttext) 
    { 
     $crypttext = base64_decode($crypttext); 
     $plaintext = ''; 
     $td  = mcrypt_module_open(self::CYPHER, '', self::MODE, ''); 
     $ivsize = mcrypt_enc_get_iv_size($td); 
     $iv  = substr($crypttext, 0, $ivsize); 
     $crypttext = substr($crypttext, $ivsize); 
     if ($iv) 
     { 
      mcrypt_generic_init($td, self::KEY, $iv); 
      $plaintext = mdecrypt_generic($td, $crypttext); 
     } 
     return trim($plaintext); 
    } 
} 


$encrypted_string = Encryption::encrypt($enc_pass); 
$decrypted_string = Encryption::decrypt($encrypted_string); 

echo $encrypted_string . "<br>" . PHP_EOL; 
var_dump($id); 
echo $decrypted_string . "<br>" . PHP_EOL; 
+2

为了防止SQL注入用[**逸出**] (http://kunststube.net/escapism),不加密!恰当地,你也不会*加密*存储密码,你*散列*它们。最好的方法是https://github.com/ircmaxell/password_compat/。 – deceze 2013-05-11 11:20:33

回答

4

事实上密码加密无关,在共同与MySQL注入。你应该(必须)分开做这些事情。

密码加密(或在这种情况下哈希)将使它无法为可能的黑客谁获得访问您的databse使用您的用户密码。哈希函数是一种方法 - 您可以从密码创建哈希,但是不需要哈希密码。从散列获取密码的唯一方法是散列每个可能的字符组合,并检查这个散列是否等于db中的这个。大多数uf用户在php中使用简单的md5()或sha256()函数。事实上它可行,但这些功能的问题在于它们的简单性。创建用于计算文件的校验和,所以它们一定很快。这就是为什么它更容易暴力。为避免被暴力强制,您可以:

a)添加'盐'并继续使用md5/sha256。 Salt是散列前添加到用户密码的随机字符串。例如,您必须在数据库中创建附加列,例如“密码”附近。每个用户应该随机获得至少32个字符长的盐。 'password'字段是使用md5(salt。users_password)创建的。如果您想在登录时检查密码 - 从数据库获取密码和盐字段,请从帖子中获取用户密码,并在数据库中比较:md5(salt。user_password_from_post)和'password'。即使用户密码很短,由于盐而变得漫长而复杂。要破解/暴力破解所有8字符密码,只需要80^8次哈希,但要破解8字符密码,您需要80^32的80^32。

b)使用河豚算法http://php.net/manual/en/function.crypt.php 河豚是从发源到crypt密码创建的。你也必须使用salt,但是你也可以指定'cost'参数,它表示hash的复杂程度。更复杂=在每次密码检查时使用更多的CPU,但也更安全。据说用河豚,16字节盐和至少10个成本确保密码是安全的。

为避免被sql注入,你应该转移传递给你的查询的每个参数。 mysql_real_escape_string()成为你的朋友。

$Query = sprintf("SELECT UserId, Password, Salt FROM Users WHERE Username='%s'", mysql_real_escape_string($_POST['Username'])); 
mysql_query($Query); 

如果

$_POST['Username'] = "'; DROP TABLE Users; --" 

你没有逃跑的查询将变成:

"SELECT UserId, Password, Salt FROM Users WHERE Username=''; DROP TABLE Users; --' 

此查询任何用户都可以摧毁你的数据库没有任何问题。随着mysql_real_escape_string,查询会看起来loke:

"SELECT UserId, Password, Salt FROM Users WHERE Username='\'; DROP TABLE Users; --' 

现在你的数据库是安全的。

用于检查密码的完整代码(你应该在DB的用户名(128),密码(32),盐(32)):

function CheckPassword($Username, $Password) 
{ 
    list($Count) = mysql_fetch_array(mysql_query(sprintf("SELECT COUNT(*) FROM Users WHERE Username='%s'", mysql_real_escape_string($Username)))); 
    if(!$Count) 
     return false; //No such user 
    list($Password_Db, $Salt) = mysql_fetch_array(mysql_query(sprintf("SELECT Password, Salt FROM Users WHERE Username='%s'", mysql_real_escape_string($Username)))); 
    if(md5($Salt . $Password) == $Password_Db) 
     return true; 
    return false; 
}