我目前正在修改我的注册脚本以添加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语句不会影响注册速度?
答案 0 :(得分:1)
循环crypt()
会使您的页面永远占用,因为Blowfish 已经使用多个散列回合,而crypt()
是散列所有实际工作的内容。因此,如果您多次运行crypt()
,则每次都会执行所有这些工作。
循环添加一些字符到盐不会影响时间,因为你没有做任何实际工作 - 只需在字符串中添加几个字符。
您不需要多次循环crypt()
;你已经在使用包含工作因素的bcrypt。
您也不需要单独存放盐; bcrypt生成的哈希包含自己的盐。