-1

So I've read this question here a few times and read all the answers. I got a semi-working system but that broke down. The problem for me is that the answers to those posts often give long, complicated code on creating the bcrtpt - but then no example as to how to put it use, ie, to respond to the first answer --

"You may use this code as such:

$bcrypt = new Bcrypt(15);

$hash = $bcrypt->hash('password');
$isGood = $bcrypt->verify('password', $hash);

"

How would I go about inputting some form data (let's call it: $user_password) into the code to create a new bcrypt to put into the data?

Furthermore, explanations of the following would help - I'm a little unsure.

  • What does the 15 within the Bcrypt function at the start mean/do? Does it mean rounds?
  • When the $isGood 'test' is carried out, I assume $isGood is turned into a Boolean (1 = true), (0 = false). So you could continue working(or not) on the login based on whether it was 1 or 0, right?
  • I'm assuming that $hash is what you'd insert into the database. If so, why can't you use the same hash on the login, rather then use the $isGood thing anyway?

I'm pretty new to php and have previously been using SHA($password) .. which is woefully easy to compare and create, so any relation between the two (or link to a conversion?) would make a much more understandable answer for me or anyone else who visits in the same situation.

Community
  • 1
  • 1
Sam Bowyer
  • 60
  • 7
  • 1
    Slides: http://ircmaxell.github.com/password-hashing-mini-presentation/ - Video: http://blog.ircmaxell.com/2012/10/password-hashing-in-php-talk.html - after watching you should know plus you get links for the code. – hakre Nov 01 '12 at 19:12
  • @hakre - Thanks for answering but that was more a overview of hashing then actually using bcrypt and interacting/using the system. – Sam Bowyer Nov 01 '12 at 19:53
  • You do not seem to have basic understanding of php. I would suggest to work through some php tutorials first. Also, have a look at the php manual on the php homepage, where you may find the API documentation of functions and classes. – Lars Nov 01 '12 at 23:29
  • @SamBowyer: You must be kidding: https://github.com/ircmaxell/password_compat - from that talk. If you would have read the talk you would have seen that this *is* using bcrypt. Plus you get the upwards compatibility with PHP. – hakre Nov 03 '12 at 10:03

1 Answers1

1

15 means strength and 15 is very slow.

Make sure you use this right or you'll get a severe performance penalty if you do verifications or hashing too often. Both operations take the same time to complete. Do a microtime() on your exact scenario. 15 is not performance friendly.

I usually use 7 - 10. More is overkill...

PS: You'll find some lengthy posts here on SO about bcrypt. Read them! Like this: https://security.stackexchange.com/questions/4781/do-any-security-experts-recommend-bcrypt-for-password-storage or this http://michaelwright.me/php-password-storage

PPS: Local test: 15 strength takes around 3 seconds. Now imagine on a shared host :) You won't probably drop under 1 second. Which is too long IMO.

ACTUAL CODE:

// Is it available on this system?
$Availability = function_exists('crypt') and defined('CRYPT_BLOWFISH');

// And now the code:
$MT = microtime(true); // Time things, so we can get scared
$Password = 'somepassword'; // The password
$Salt = 'addsomevalidsalthere'; // Your salt, must be valid, read docs
$Strength = 15; // Strength (1-99)
// Compute the formatted salt required for crypt
$CryptSalt = sprintf('$2a$%02d$%s$', $Strength, $Salt);
// Hash the use $Password for storage
$Hashed = crypt($Password, $CryptSalt);
// Verify it against the user input $Password
$Verified = crypt($Password, $Hashed) === $Hashed;
// Show the duration of this (2x as it's both in and out)
echo number_format(microtime(true) - $MT, 6), PHP_EOL;

It's documented. Use for testing.

Just don't design your code to test the hash on each page load. That will kill your site's performance.

  • Hash when creating a new user or changing the password.
  • Verify when logging in an user.
  • And in the rest, use some hashing mechanism that's fast to test on each logged-in page load.

You'll notice when you're doing it wrong. In your site's load speed :)

EXPLANATION:

When you hash with blowfish crypt, you need a salt, a strength and a password. You combine the salt and strength as the specs requires you to and you create a crypt() compatible salt. This salt is translated by crypt() and the sale and strength is extracted, plus the hashing algorithm based on character 2 and 3.

In your database, you store the final hash value. You don't store the salt you used to hash the password as you will defeat the purpose. The hashcrypted value stores what it needs to perform the reverse operation and check if your plain password matches the hashed one. The salt is stored within, no need for you to store it.

When the user is registered, you hash the password and save it. When they login, you verify the hashed password against the plain one they submit in your form. No need to remember the hash used to hash. And this allows you to generate random hashes on each hashing without caring what that value is as it's bundled in the returned hash. See more on the crypt() page on php.net.

Let me know if this made sense.

Community
  • 1
  • 1
CodeAngry
  • 12,760
  • 3
  • 50
  • 57
  • You can not call absolute values for these an absolute behaviour. Those absolute values are relative to the hardware running on. The right answer is to test with the application on the hardware where that is running on. – hakre Nov 01 '12 at 19:21
  • @hakre Told him to microtime() it. 15 is most certainly in 2,500+ millisecond range. – CodeAngry Nov 01 '12 at 19:27
  • Ok. So the Bcrypt is just a definition of how the bcrypt used in later code should work. – Sam Bowyer Nov 01 '12 at 19:29
  • - And you just replace password with $user_password, get a boolean back and run with whether it's ! or not? – Sam Bowyer Nov 01 '12 at 19:30
  • @SamBowyer Now sure what you're asking so I dropped some documented code for you to look over and figure it out. – CodeAngry Nov 01 '12 at 19:40
  • 1
    @Claudrian I've tested the code, yes crypt is available and I see how it works and 1 is returned if verified. I'm going to put this into use now; thanks for the revisions and example code which has made this a lot eaiser to understand. +1 & tick'd. – Sam Bowyer Nov 01 '12 at 19:52
  • @SamBowyer Glad you got it. Just make sure 15 is a viable value for your load times :) – CodeAngry Nov 01 '12 at 19:53
  • @Claudrian Can I ask why $Verified is included? Can't you put the $Hashed into the database as password on sign up & look for a row containing the $Hashed calculated on login to verify? – Sam Bowyer Nov 01 '12 at 19:59
  • @SamBowyer Edited it. Read now and let me know if it makes sense. – CodeAngry Nov 01 '12 at 20:12
  • What troubles me is: $Verified = crypt($Password, $Hashed) === $Hashed; – Sam Bowyer Nov 01 '12 at 20:19
  • @SamBowyer That's for the login sequence. I added it there just keep the flow. But you can remove that line. Use it only when you test login credentials against the hashed password in your DB :) – CodeAngry Nov 01 '12 at 20:20
  • Pressed enter to make a new paragraph accidently. To restart: What troubles me is $Verified = crypt($Password, $Hashed) === $Hashed; - which of those inputs is the user password & hash? Would it be: $Verified = crypt(passwordgaveinform, hashformdatabase) === Hashworkedoutfrompasswordgaveinform ? – Sam Bowyer Nov 01 '12 at 20:20
  • `$Verified = crypt($passwordgaveinform, $hashformdatabase) === $hashformdatabase;` – CodeAngry Nov 01 '12 at 20:22
  • " test login credentials " - Ah, I think I've got it, so in the log in script, I just add the last line to check, leaving $Password = as the password gave by the login form, then work with whether it is 1 or 0 (true/false). – Sam Bowyer Nov 01 '12 at 20:22
  • Ok thanks. Away to test. – Sam Bowyer Nov 01 '12 at 20:22