【发布时间】:2012-08-11 13:40:56
【问题描述】:
此功能对于密码和电子邮件哈希/加密是否安全?编辑:显然不是!
$password = mysql_real_escape_string(htmlspecialchars(trim($_POST['password'])));
$hash_algo = "sha512";
$raw_output = false;
$hash = hash($hash_algo, $password, $raw_output);
$hash_20 = substr($hash, 0, 20);
$salt = substr($hash, -20);
$crypt = crypt ( $hash_20, $salt);
$crypt_20 = substr($crypt, 0, 20);
编辑: 这是我现在使用的代码。我觉得这个很安全。这是一个带有随机盐生成器的 PBKDF2 密码哈希函数。
所以,这里是 PBKDF2 函数。 p 是密码。 s 代表盐。 c 用于迭代 kl 是键长。 a 是哈希算法。
function pbkdf2( $p, $s, $c, $kl, $a = 'sha256' )
{
$hl = strlen(hash($a, null, true)); # Hash length
$kb = ceil($kl / $hl); # Key blocks to compute
$dk = ''; # Derived key
# Create key
for ( $block = 1; $block <= $kb; $block ++ ) {
# Initial hash for this block
$ib = $b = hash_hmac($a, $s . pack('N', $block), $p, true);
# Perform block iterations
for ( $i = 1; $i < $c; $i ++ )
# XOR each iterate
$ib ^= ($b = hash_hmac($a, $b, $p, true));
$dk .= $ib; # Append iterated block
}
# Return derived key of correct length
return substr($dk, 0, $kl);
}
盐发生器:
function salt( $length )
{
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$salt="";
$size = strlen( $chars );
for( $i = 0; $i < $length; $i++ )
{
$salt.= $chars[ rand( 0, $size - 1 ) ];
}
return $salt;
}
使用中:
if(isset($_POST['submit']))
{
$Password = mysql_real_escape_string(htmlspecialchars(trim($_POST['Password'])));
//To make sure the salt has never more chars than the password.
$salt_length = strlen($Password);
$salt = salt($salt_length);
//Hash Password
$hash = base64_encode(pbkdf2($Password, $salt, 100000, 32));
//--------------//
}
谷歌搜索一下,发现 100000 次迭代非常安全,但我想 10000 次就足够了。
【问题讨论】:
-
另外,不需要
mysql_real_escape_string(htmlspecialchars($password));,你正在散列它,这几乎可以处理所有事情。输出将始终为十六进制字符串。 -
“安全”反对/为了什么?
-
我很抱歉这么说,但没有。不,你没有读完所有这些。如果您已阅读所有内容,您将能够回答这个问题。这些问题为您提供了评估您自己的代码并确定它是否安全所需的工具和知识。
标签: php security hash passwords crypt