-4

此功能对密码和电子邮件哈希/加密是否安全?编辑:显然不是!

$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 次就足够了。

4

1 回答 1

3

由于您正在对输入进行散列处理,因此您不能简单地将其反转为原始值。假设攻击者知道这个算法,那么问题是暴力破解密码需要多长时间。为此,测试一次算法迭代需要多长时间。然后计算攻击者必须尝试多少次才能在高端机器上尝试所有可能的密码。然后你就知道算法有多“安全”了。您正在寻找至少以千年为单位的答案,但最好是大爆炸。

也就是说,假设没有针对攻击者可以尝试的算法的实际攻击,这将缩短该时间。

由于您是从输入本身导出盐,因此您只是稍微扩展了算法。您没有使用实际的盐,它是一个独立于输入的随机唯一值。因此,您正在使用具有不那么复杂的散列算法的未加盐输入。我敢打赌,用这种算法蛮力“保护”整个密码数据库并不难。

于 2012-08-15T08:48:49.350 回答