2

I'm trying to make a more or less secure login system for my site, I haven't had much time with securing things so I'm learning as I go along. Wanted to hear some views on which of the following is better and why. (or have I made a mistake somewhere?)

$staticsalt = '$%*#)$*)^A#$#543667ggfdf\#$%x';  
$random = md5(uniqid(mt_rand(), true));
$salt = hash('sha512',$random.$_POST['password'].microtime().$staticsalt);

either (where having the $salt in the database won't be necessary...)

$password = crypt($_POST['password'], '$2a$12$'.$salt);   

or (where I would need the $salt in the database also...)

$password = hash('sha512',$salt.$_POST['password']);
wark91
  • 53
  • 1
  • 5
  • Are you planning on storing the `microtime()` you're adding so you can add that to back to your password check? – Jared Farrish Aug 14 '11 at 10:42
  • no I don't need to, first case the generated $password already has a copy of the salt (i.e. to check you only need to $password = crypt($_POST['password'], $password); ), the second case the $salt is stored in the database for each user. – wark91 Aug 14 '11 at 10:43
  • From what that seems to demonstrate, if you do not save the `microtime()` value generated, you will never be able to check the hash that is generated including it. You have to be able to rebuild the entire input. – Jared Farrish Aug 14 '11 at 10:45
  • @Jared He's generating the **salt** using `microtime` as randomizer. I overlooked that as well at first... – deceze Aug 14 '11 at 10:46
  • You can use [mcrypt_create_iv](http://php.net/manual/en/function.mcrypt-create-iv.php) to generate a random salt. It uses data from `/dev/random` or `/dev/urandom`. – Mike Aug 14 '11 at 13:01

3 Answers3

3
  1. SHA512 is quite a fast algorithm, which is usually an undesirable attribute for password hashing algorithms.
  2. Using a predictable value such as microtime as random seed for the salt may open you up to some advanced attacks that a more random value would prevent.

I recommend phpass, which is a good existing implementation of a password hashing system.
http://www.openwall.com/phpass/

deceze
  • 510,633
  • 85
  • 743
  • 889
  • When not using crypt, the salt is obviously saved in the database along with $password. – wark91 Aug 14 '11 at 10:50
  • @wark Yeah, sorry, I totally misinterpreted what you're doing with your salt. I removed those points. – deceze Aug 14 '11 at 10:54
  • @wark91 - There's also the option of using the user's created date/time if you keep it. Then you wouldn't need to keep the salt. – Jared Farrish Aug 14 '11 at 10:55
  • @Jared Then the date/time is basically the salt, and one with a really low entropy at that. – deceze Aug 14 '11 at 10:56
  • I'm talking about generating the salt in the same manner, just slotting in a created time stamp instead of `microtime()`. I just don't know that I'd want to store the salt next to the password in the db. But, to be honest, I don't know the answer to which one would be less secure. – Jared Farrish Aug 14 '11 at 11:05
  • @Jared So you're storing a value in your database (the timestamp) which you're putting through a simple algorithm and then use as a salt. Contrast that with storing a value in your database (the salt) which you may or may not put through an algorithm and then use as a salt. It's the same thing really, so the timestamp has essentially become the salt. Also, salts are *not secret*. They're supposed to raise computational complexity, not to be an additional secret. – deceze Aug 14 '11 at 11:09
  • @Jared "Proper use of salts may defeat a number of attacks, including: Ability to try candidate passwords against multiple hashes at the price of one; Use of pre-hashed lists (or the smarter "rainbow tables") of candidate passwords; Ability to determine whether two users (or two accounts of one user) have the same or different passwords without actually having to guess one of the passwords. Salts are normally stored along with the hashes. They are not secret." http://www.openwall.com/articles/PHP-Users-Passwords – deceze Aug 14 '11 at 11:12
  • Maybe some $random = md5(uniqid(mt_rand(0x19A100, 0x39AA3FF), true)); or $random = md5(uniqid(mt_rand(), true)); added to the $salt? And tnx I'll take a look at the phpass link. – wark91 Aug 14 '11 at 11:52
  • @wark Also see http://stackoverflow.com/q/7047741/476, which doesn't really have a definite answer yet though... – deceze Aug 14 '11 at 11:58
  • @deceze - I actually don't do that at all. But I can see that I probably shouldn't. ;) – Jared Farrish Aug 14 '11 at 14:21
0

Don't hash your salt like that.

crypt's Blowfish hashing takes a 22-character base64-encoded string (using characters [./0-9A-Za-z]) for a salt, which amounts to 128 bits of entropy.

The SHA-512 hash you're using to create your salt has 512 bits of entropy. But you're throwing away more than 80% of that since crypt will now only use 22 lowercase, hexadecimal characters. That leaves you with only about 85 bits of entropy despite all the fancy randomness-generating you're doing.

And if 85 bits is good enough for you, you might as well just do something like this:

$salt = str_replace("+", ".", base64_encode(md5(uniqid(mt_rand(), true), true)));

I don't really dare to give you any advice on how to generate a salt that does use the full 128 bits, since I'm not a cryptography expert.

mercator
  • 28,290
  • 8
  • 63
  • 72
  • I originally used the $password = hash('sha512',$salt.$_POST['password']); which to me sounds ok when combined with some delay + limiting of consequent tries, and tries per day, etc. As for what I wrote I am aware of the lengths, but regardless was interested to find out views on which way of the two would be the better way to go. – wark91 Aug 14 '11 at 15:56
-2

Actualy there is no point to ad so much security. You have to know for what your system is made for. If its just some chat, then you will be fine with md5. If its banking system, well then you must have some real authentication system, i mean some of card with salts or code generator.

EDIT: I dont thing that there is one good security policy. Upper answer is great, thought.

Ernestas Stankevičius
  • 2,420
  • 2
  • 24
  • 30
  • 3
    Security goes both ways. The problem is that many users use the same password all over the interwebs. If your chat system database falls into the wrong hands and the passwords can be reverse engineered, you have compromised the security of your users *at other web services* with your "md5 is good enough for me" mentality. Yes, it's a problem of users reusing the same passwords, but it's a reality and will be bad publicity for **you**. – deceze Aug 14 '11 at 10:51
  • 2
    There should be a differentiation between an over-engineered/poorly engineered system, and a system that implements proper security techniques. So two-factor logins (with random key dongles or whatnot) for a chat setup would probably not be needed, but storing the passwords with a proper amount of caution and utilizing solid and modern techniques should be accomplished. Putting novices in charge of a login system may lead more to a Rube Goldberg machine, which isn't useful. But that does not have to be the case. – Jared Farrish Aug 14 '11 at 10:58
  • Ágree. But md5 and some slat isnt bad, till you know hove to secure all your site. – Ernestas Stankevičius Aug 14 '11 at 10:59