执行PHP脚本时达到内存限制

时间:2012-12-25 15:57:34

标签: php hash iteration salt bcrypt

我目前正在修改我的注册脚本以添加PDO和bcrypt。但是当我尝试迭代哈希时,我遇到了一个错误。我最初设置为10000,因为我看到轮次为60000+的教程,但这需要很长时间。所以我把它设置为2只是为了测试它然后我得到一个错误:

[Tue Dec 25 10:45:07 2012] [error] [] PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 133431193 bytes) in /var/www/register_script.php on line 28, referer: 

我的整个注册脚本都是休闲:

<?php 
//Minor work needed need to finish user verification 


$host="localhost"; // Host name
$username="root"; // Mysql username
$password="testdbpass"; // Mysql password
$db_name="test"; // Database name

// Connect to server via PHP Data Object
$dbh = new PDO("mysql:host=localhost;dbname=test;", $username, $password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

CRYPT_BLOWFISH or die ('No Blowfish found.');

// Creating the salt
$Blowfish_Pre = '$2y$15$';
$Blowfish_End = '$';


$Allowed_Chars =
'/.ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$char_len = 63;

$salt_length = 60;
for($round=0;$round<$salt_length;$roundi++)
{
    $salt .= $Allowed_Chars[mt_rand(0,$char_len)];
}
$bcrypt_salt = $Blowfish_Pre . $salt . $Blowfish_End;
//Salt creating stops here

//Creating the hash and password
$password = $_POST['password'];

$hashed_password = crypt($password, $bcrypt_salt);
for($round=0; $round<2; $round++)
    {
        $hashed_password = crypt($password, $bcrypt_salt);
    }

// Insert statements with PDO 

try {
        $query = $dbh->prepare("INSERT INTO `users_blowfish` (username, email, fname, lname, salt, password) 
                               VALUES (:username, :email, :first, :last, :salt, :hash)");

        $query->execute(
                        array(
                        'username' => $_POST['username'],
                        'email' => $_POST['email'], 
                        'first' => $_POST['fname'],
                        'last' => $_POST['lname'],
                        'salt' => $bcrypt_salt,
                        'hash' => $hashed_password
                        )); 
    }

    catch (PDOException $e) {
        error_log($e->getMessage());
        die($e->getMessage());
    }

    $dbh= null;

    ?>

<html>
    <body>
        <p> 
            Thank you for registering your account. Please wait for administrator approval before doing anything else. Thank you - System Administrator. 
        </p>
    </body>
</html> 

如果我拿出for语句:

$hashed_password = crypt($password, $bcrypt_salt);
for($round=0; $round<2; $round++)
    {
        $hashed_password = crypt($password, $bcrypt_salt);
    }

然后一切正常。然而令我困惑的是,我有两个声明上面的那个^

和这一个:

$salt_length = 60;
for($round=0;$round<$salt_length;$roundi++)
{
    $salt .= $Allowed_Chars[mt_rand(0,$char_len)];
}

我想我总结的问题是 1)为什么散列的for语句使注册速度极慢,而salt创建的for语句不会影响注册速度?

1 个答案:

答案 0 :(得分:1)

循环crypt()会使您的页面永远占用,因为Blowfish 已经使用多个散列回合,而crypt()是散列所有实际工作的内容。因此,如果您多次运行crypt(),则每次都会执行所有这些工作。

循环添加一些字符到盐不会影响时间,因为你没有做任何实际工作 - 只需在字符串中添加几个字符。

您不需要多次循环crypt();你已经在使用包含工作因素的bcrypt。

您也不需要单独存放盐; bcrypt生成的哈希包含自己的盐。