I'm writing a first attempt at a user login system and would like to get it right. I feel I'm in duplicate territory here but for all my reading haven't been able to find a solid answer to a few questions. If I've missed something however, please feel free to point me in the right direction.
I will be using 128bit per user salts on all passwords, and enforcing "strong" (subjective I know!) passwords but can't work out what is the best way to hash them so,
Would using
CRYPT_SHA512
with iterations ever be as strong as usingCRYPT_BLOWFISH
?Is there aWhat is the difference bet开发者_开发问答ween CRYPT_SHA512 with iterations, and repeatinghash_hmac
usingsha512
a (large) number of times. Is one better than the other and which is recommended for hashing passwords? I ask because I'm using Kohana and the defaultauth
implementation useshash_hmac
. I don't think it will be too hard to add iterations to that (and I'm going to have to modify it to add per user salts anyway), which leads me on to ..Is there a module to do this already available for Kohana (3.1)? Before I go about writing my own, if there's something out there that is suitable I'd be happy to use that. So, something that performs hash stretching (be it bcrypt or sha512) and allows per user salts. And finally,
... as pointed out in comments, question 4 is really a separate question entirely so I'm getting rid of it. Feel free to ignore it. The only reason I won't edit it out completely is that it is already referenced in an answer.
4. My system will allow users with different privileges.
Some will be administrators with
full rights, some developers with
slightly lesser rights, all the way
down to anonymous users with rights
to only leave comments for example.
I haven't been able to find any
information about this really. What
is the "correct" way to store a user
account type in the database. A
naive first thought is that a simple
integer in the user table would
suffice, but I can't help thinking
this is a terribly bad idea. If
someone gets hold of the database it
wouldn't be hard to work out which
int
represents an administrator,
then they only need to brute force
one password to gain full access
rights. Would it suffice to simply
hash the account type integer and
store that, or should I be looking
at another method?
The answer to questions 1-3 is really one answer, composed of several parts.
Firstly, you should be using a strong hash with per-user salts. In particular I would suggest PBKDF2 which is a useful system for this. That includes iteration.
Your reference to bcrypt is a bit different. Passwords should always be one-way hashed. You can use a function like PBKDF2 or a hmac to do this. You shouldn't use a reversible algorithm. However it is best if you can store the salt away from the hash itself. One suggestion for doing this is to bcrypt the salt with a key that is accessed from the file system, not the database. Preferably in a file with 600 permissions owned by someone other than the webserver user and loaded by setuid or the like. This way even if the database is compromised there still isn't enough information to derive the password.
Part 4 is about data structures to store ACLs. There are lots of options for that so have a look around for something which suits you. You might not need a full-blown ACL, instead just having user roles/groups or particular permission flags. This will depend on your application.
精彩评论