使用加密函数在mysql数据库中加密安全密码
我想加密密码以防止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;
事实上密码加密无关,在共同与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;
}
为了防止SQL注入用[**逸出**] (http://kunststube.net/escapism),不加密!恰当地,你也不会*加密*存储密码,你*散列*它们。最好的方法是https://github.com/ircmaxell/password_compat/。 – deceze 2013-05-11 11:20:33