//generating Excel File
$setSql = "SELECT * from demo table";
$setRec = mysqli_query($db, $setSql);
$header_name="DATA LIST IN EXCEL";
$Event= "This is a demo";
date_default_timezone_set("Asia/Kolkata");
$date='Export Date:-'.date("l, jS \of F Y h:i:s A");
$columnHeader = '';
$columnHeader = "Name" . "\t" . "Date" . "\t". "Mode No" . "\t". "Address" . "\t". "eduction"."\t"."Organisation" . "\t". "Paid Status" . "\t";
$setData = '';
while ($rec = mysqli_fetch_row($setRec)) {
$rowData = '';
foreach ($rec as $value) {
$value = '"' . $value . '"' . "\t";
$rowData .= $value;
}
$setData .= trim($rowData) . "\n";
}
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename= file_name.xls");
header("Pragma: no-cache");
header("Expires: 0");
echo $header_name ."\t\t\t\t\t\t\t\n". $Event ."\t\t\t". $date ."\n". ucwords($columnHeader) . "\n" . $setData . "\n";
答案 0 :(得分:2)
首先...
相反,只需使用password_hash和password_verify,并且进行自己的加密(散列)是一个坏主意。也不建议在没有适当安全知识的情况下进行用户登录系统。
但是,为了争辩(由于准备好的语句,这不起作用):
public static function make($string, $salt = ''){
if(empty($salt)) $salt = self::salt(rand(10,20)); //if you do this make sure the field is big enaugh
return hash('sha256', $string . $salt).$salt; //add salt to end of password
}
public static function salt($length){
return openssl_random_pseudo_bytes($length);
}
public static function authenticate($username, $password)
{
//prepare your queries!!!! (see below)
$sql = 'SELECT * FROM users WHERE email = ? AND status = 1'; //do not look up the password
/*
other DB code here
*/
$found = self::read($sql, PDO::FETCH_CLASS, __CLASS__);
if($found){ //should check for only 1 row returned as usernames should be unique index in the DB
$row_pass = substr($row['password'], 0, 64); //pull password from DB
$row_salt = substr($row['password'], 64); //pull salt from password
//security compare hashes, in a safe way
if(hash_equals($row_pass,self::make($password, $row_salt))){
echo '<div class="alert alert-success text-center">
<strong>Found</strong>
</div>';
}else {
echo '<div class="alert alert-danger text-center">
<strong>Not Found</strong>
</div>';
}
}
请参阅http://php.net/manual/en/function.hash-equals.php
一些笔记
$encpassword = Hash::make($password);
$row
放在其中。UTF8-bin
或UTF8二进制,然后在搜索时区分大小写(可选)。SQLInjection 如果我通过(对您的方法进行身份验证)
$username = "' OR 1 LIMIT 1 --";
我会通过此查询(这是最常见的攻击类型之一)来绕过您的登录
$sql = "SELECT * FROM users WHERE email = '' OR 1 LIMIT 1 --' AND password = '".$encpassword."' AND status = 1";
--
是SQL中注释的开始,因此之后没有任何关系,OR 1
始终为真。哪一个(有限制,您甚至不检查仅一个返回行)都会(每次)返回1行,并以$found
绕过登录true
。不创建自己的登录系统的众多原因之一。
换句话说,无论您多么难以设置密码,现在我都可以使用LIMIT和OFFSET以所需的任何人身份登录到您的网站。显然应该避免一些事情。
另一种方法是将盐单独保存并从表中检索出来。但是,没有关于您最初如何设置和保存密码的代码。所以我就这样走了。另外,我将不深入讨论如何正确准备查询,有很多有关如何执行查询的示例,并且由于缺少有关如何使用数据库的代码,因此没有用。
正如我在评论中所说
salt的目的不仅是减少哈希的可猜测性,而且还可以防止来自字典列表和彩虹表(预先完成的哈希)的攻击。如果知道这一点,例如攻击者控制了数据库,那么它仍然使他们的任务变得复杂,因为他们必须为每个密码重做彩虹表。他们将遭受暴力或字典攻击
加盐的想法是为每个密码赋予不同的密码,然后攻击者无法使用庞大的已编译哈希表(彩虹表)数据库来获取密码。通过使该词不是一个明智的词,还会使字典攻击(从站点外部)变得复杂。
在使用彩虹表的情况下,即使攻击者知道了盐也没有帮助(他们需要为每个密码重新编译彩虹表中的所有哈希,这时攻击者会更好使用以下两种方法之一)。在字典表的情况下,它们必须以完全相同的方式包含盐,并且在蛮力的情况下(即使他们有盐也可能不知道)。即使他们都知道这两个方面,但如果您从不加盐,那也不会比他们更好。更糟糕的是,除非它是有针对性的攻击,否则它实际上消除了彩虹表。正如我所说的,即使在这种情况下,当他们重做彩虹桌时,他们也可以蛮力地将它撞上。
因此,上面的观点是,盐的安全性并非来自攻击者是否知道它。因此,将其存储在数据库中是安全的,因为如果攻击者可以获取数据库,则他们可能仍然拥有您的服务器,并且您会遇到更大的问题。而且它无济于事,因为在最坏的情况下他们可以将其强行使用,但不使用彩虹表,即使已知,它也会使字典攻击变得复杂。
希望这一切都有道理。