5

Background:

I want to add a login to my small site, which is an online php application, which I'd like to build to be able to bear much user activity in the future.

Before I look further into implementing LightOpenID I want to add a normal login. The book I was learning from is called Head First PHP & MySQL (2008) and the final code of the chapter uses SHA('$user_password') as part of the mysql query.

As I take interest in Jeff Atwood's writing I'm well aware of bcrypt as of scrypt. But seen as there's no php implementation of scrypt and having no dedicated server to run it, I decided to at least look into implementing bcrypt for now.

However I'm not completely naive, I know I should watch out not to overextend my very humble hosting resources. The php app itself should always come first before anything else concerning resources.

Andrew Moore's method seems nice (though I'll have to see how to implement it on php 5.2.17 which my host uses) and it comes with a tip for hardware speed:

You should select a number of rounds that results in 200-250 ms of work. Part of the reason why bcrypt is secure is that it is slow. You must ensure to have a number of rounds that keeps that characteristic. – Andrew Moore

Another user states that for him running microtime() gives 0.314 for Bcrypt(9), which thus would be near optimal.

The question:

Seen as I only have very humble resources at my disposal and I'd like to make the best of them, leaving most for the php app itself, am I still better off using Bcrypt(4) instead of something else?

Bcrypt(4) returns true almost instantly, but does it still keep that characteristic Moore talks about?(Would that be the part concerning RAM that makes it harder for GPU bruteforcing?) Or would SHA512 or something else actually be as fast but more secure at this point?

I'd expect Bcrypt(4) to win in this situation, but the hell do I know right? :p

Community
  • 1
  • 1
Suzy
  • 75
  • 6
  • 5.2 is ancient. Either yell at, or replace, your host. – Madara's Ghost Jul 28 '12 at 20:32
  • It's a very decent host otherwise, while being amazingly cheap, I think this is more of a upgrade to a virtual dedicated server, than a change host entirely, issue. Which is something for the feature. – Suzy Jul 28 '12 at 20:43

3 Answers3

5

Security is always about what you are trying to secure.

If you are more concerned about your resources than about your security, bcrypt(2) is already overkill. No hacker will ever try to break that for a normal application, having easier target sites like LinkedIn and many others, which just use functions from the sha family, with a single iteration, and unsalted. They will go for the 'low hanging fruit'. Or they could keep trying to hack your application, just not in the password encryption part.

SHA-512 is not much more secure than SHA-1 as password hashing algorithm [1], it has not been designed for that purpose. They can still be used as primitives for creating secure cryptographic algorithms though, but that's something no single person should do. To be considered secure, crypto algorithms must be public to be peer reviewed, and must pass the test of time. And obviously, must be designed for what you are going to use them. MD5, SHA-X, etc. are cryptographic algorithms, but weren't designed for storing passwords.

Just add or remove rounds to your bcrypt. In this case I would use 1 or 2. Also keep in mind that 1 round != 1 iteration. They are increased exponentially. If you read about how bcrypt works, you will see that there is much more to it than just iterations. For example, you mentioned 'unique salt per password'. Bcrypt already has that.

[1] For other things it's obviously more secure

ChocoDeveloper
  • 14,160
  • 26
  • 79
  • 117
  • I didn't put much focus on details of the log part, as I understood it 4 stands for `$log_2_rounds` which is "log of the round count" (as Matthew Flaschen wrote in the comments there). And yes I know that the salt is already an integral part of the generated hash in bcrypt. – Suzy Jul 28 '12 at 20:31
  • @Suzy Well I'm sorry that you didn't like my answer, but you are not gonna find anything better than bcrypt. You already know scrypt, but you won't be able to take advantage of it. And even if you could, there's no point in worrying about this. – ChocoDeveloper Jul 28 '12 at 20:43
  • I didn't said I didn't like your answer :p It's informative, I'm just not immediately hitting accept on the first answer I get. – Suzy Jul 28 '12 at 20:49
  • My main intention btw is protecting the passwords of the users when the attacker has already breached server security and has access to the database. I'm not sure how the hacker would know what type of hash I use before he's already inside. – Suzy Jul 28 '12 at 20:57
  • @Suzy Yes, ciphers and password hashing algorithms designers always assume the hacker has access to the encrypted message or password *and* the algorithm used to encrypt them. And in the case of password hashing algorithms like bcrypt, they can even have access to the salt, because it comes bundled with the resulting hash. – ChocoDeveloper Jul 28 '12 at 21:12
  • @Suzy There are methods for knowing which algorithm has been used, without looking at the code. I can recognize many of them just by looking at them, but for non obvious ones, there is a discipline called cryptanalysis. Trying to hide the algorithm used is called security through obscurity, and is not recommended. Not that you should publish which algorithm you used either (unless you want your users to know how secure your app is, which might be a good thing), but hiding it won't improve your security, and you shouldn't depend on that. – ChocoDeveloper Jul 28 '12 at 21:15
  • 2
    "SHA-512 is not much more secure than SHA-1, it has not been designed to be so." **That's incorrect**. The although SHA-512 is uses similar techniques to SHA-1, the inner workings of a round of SHA-512 are much more complex and more difficult to break. The inner block size and output size have been expanded as well. Why do you think they designed the SHA-2 family in the first place? It's not speed, SHA-1 is faster than any SHA-2 algorithm. – Maarten Bodewes Jul 28 '12 at 22:05
  • @Truth: -1 for suggesting bcrypt(2) is "already overkill" and the clearly invalid information about SHA-512. [edited for Truth to see my explanation] – Maarten Bodewes Jul 28 '12 at 22:17
  • @owlstead We are talking about storing passwords. For storing passwords it's not more secure. You can go on and philosophy about SHA-512 being slower than SHA-1 or whatever, it is still not designed for that, so using it for that is just wrong and insecure. As I said, they are used as primitives for other cryptographic matters, but not for encrypting passwords by themselves. You can use SHA-X as primitive for implementing bcrypt, for instance. From my score you can tell I don't care about points, be my guest and downvote if it makes you feel better. – ChocoDeveloper Jul 28 '12 at 23:26
  • 2
    @ChocoDeveloper I'm downvoting as the the information that I've indicated is incorrect. This is a question about security and your advice should take that into account. I'm not trying to bash you in any way, and I would be happy to upvote instead if you change or update the information. You could e.g. indicate that using SHA-1 or SHA-2 isn't all that important for key derivation functions, instead of the blanket statement that "SHA-512 is not much more secure than SHA-1". Your answer is otherwise certainly correct. – Maarten Bodewes Jul 28 '12 at 23:40
2

You should look at security of the system, not just of bcrypt.

Certainly, if you want to store passwords, bcrypt or PBKDF2 is the way to proceed. Make sure you use a sufficiently large, random salt per user or password. Then try to maximize the number of iterations. If that's small, then it is small, but any iteration more is better than nothing.

Note that this does little against eavesdropping or man in the middle attempts (MitM). You should use SSL for that; the password or the hash (if you do the hashing client side) can be replayed otherwise.

Furthermore, if you want to protect against brute force attacks (attackers trying the most common passwords) you should create (or copy) a good password management scheme. Limit the amount of incorrect logins and try to let the users create strong passwords. Also limit the amount of information you return to your user regarding incorrect logins, that user may be the attacker.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • Yeah I was already planning on setting something up to force users into creating safe passwords. And even of making a small paragraph explaining as to why it matters and suggesting semi-passphrases. =) – Suzy Jul 29 '12 at 18:18
  • I'll look into client side hashing later, I'm not sure if there are downsides to it other than running it in slower javascript on a possibly very slow machine, which perhaps makes it require a speed test. But it could give the user the option to choose his/her own iteration count! (along with taking some strain off the server!) – Suzy Jul 29 '12 at 18:28
  • What exactly do you mean with "limit the amount of information" though? Would it be wrong to communicate the amount of attempts left for the chosen time interval? Like: "You have 4 attempts left, after that you'll have to wait 1 hour before trying again." – Suzy Jul 29 '12 at 18:31
  • E.g. many sites nowadays say "username and password combination are invalid" instead of mentioning which one is wrong. Returning how many login attempts are left may be required not to piss your users off, of course. Nobody is helped with an uber secure system that nobody uses. But mentioning that you've got one attempt left may be enough. – Maarten Bodewes Jul 29 '12 at 21:03
1

Or would SHA512 or something else actually be as fast but more secure at this point?

Slowness is a major feature of password hashing algorithms (of which, bcrypt is one, but SHA-512 by itself is not) - the slower your algorithm is (relative to other algorithms), the harder it is for an attacker to brute force passwords based on the hashes. From this perspective, a single round of SHA-512 is less suitable than bcrypt for the purpose of securely storing passwords, because it is considerably faster.

In my opinion, the best approach to take is to pick a password hashing algorithm (bcrypt, PBKDF2, scrypt) and then tune the work factor to give you the best tradeoff between speed and security, given the computing resources available to you and the characteristics of your system. A higher work factor = more secure, but also more resource-intensive.

The good news is that users typically use your login function infrequently compared to other functions, so the impact of a slower/resource intensive login function is generally not a big problem.

Spencer Uresk
  • 3,730
  • 26
  • 23