Достигнут предел памяти при выполнении PHP-скрипта

В настоящее время я пересматриваю свой сценарий регистрации, чтобы добавить 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);
    }

Тогда все работает. Однако меня смущает то, что у меня есть два утверждения for, одно из которых выше ^

и этот :

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

Я предполагаю, что мои вопросы резюмируются так: 1) Почему инструкция for по хэшу делает регистрацию чрезвычайно медленной, а инструкция for по созданию соли не влияет на скорость регистрации?


person Rixhers Ajazi    schedule 25.12.2012    source источник
comment
Вам не нужно вручную реализовывать раунды для bcrypt. Не создавайте собственные, используйте то, что уже существует, например openwall.com/phpass.   -  person Amber    schedule 25.12.2012


Ответы (1)


Зацикливание на crypt() делает вашу страницу бесконечной, потому что Blowfish уже использует несколько раундов хеширования, а crypt() выполняет всю фактическую работу по хэшированию. Поэтому, если вы запускаете crypt() несколько раз, вы каждый раз выполняете всю эту работу.

Циклическое добавление нескольких символов к соли не влияет на время, потому что вы не выполняете никакой реальной работы — просто добавляете несколько символов в строку.

Вам не нужно перебирать crypt() несколько раз; вы уже используете bcrypt, который включает в себя фактор работы.

Вам также не нужно хранить соль отдельно; хэш, созданный bcrypt, содержит собственную соль.

person Amber    schedule 25.12.2012
comment
Ах… спасибо, что разъяснили, что для меня я как бы думал об этом, но хотел, чтобы меня успокоили. Большое спасибо. И с праздником :) - person Rixhers Ajazi; 25.12.2012