PHP密码功能


PHP password function

这个函数对密码和电子邮件哈希/加密是安全的吗?编辑:清除不是!

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

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

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

由于您是从输入本身派生盐的,因此您只是稍微扩展了算法。您没有使用实际的盐,这是一个独立于输入的随机唯一值。因此,您使用的是具有不那么复杂的哈希算法的无盐输入。我敢打赌,用这种算法"保护"整个密码数据库并不难。