1

I've made the below function to make a completely random 64 character long hash

   function password_salt($password){
    $salt = hash("sha512", mt_rand(1,100000) . strtotime("now") . $password . "ewuwmeqwjkeq 7689" . hash("sha256", strtotime("now - 10 days") . $password));
    $salt = $salt . $password;
    for ($i=0;$i<10000;$i++){
        $salt = hash("sha512",$salt);
    }
    $hash = $salt . $password;
    for ($i=0;$i<10000;$i++){
        $hash = hash("sha512",$hash);
    }
    $salt = hash("sha512", mt_rand(1,100000) . strtotime("now") . $password . $hash . "ewuwmeqwjkeq 7689" . hash("sha256", strtotime("now - 10 days") . $hash . $salt) . $salt);

    //salt is almost ready for production
    // go salt part 2
    $salt2 = hash("sha512", $salt . $salt . $salt . $password . mt_rand(1,100000) . "dsjdj3y87Yhuu(&^TYUGh" . hash("sha512", $salt . $salt . $password . $salt));

    //hash salt . salt2 . salt . salt2 . salt2 . hash salt2 timestamp
    $salt = hash("sha512", $salt . $salt2 . uniqid(rand(), true) . $salt . $salt2 . $salt2 . hash("sha512", $salt2 . strtotime("now")));

    // go salt 3
    $salt3 = hash("sha512", $salt2 . $salt . $salt2 . $password . mt_rand(1,100000) . "DMDJ3908_))O l;[h" . hash("sha512", $salt . $salt2 . $password . $salt2));

    //final salt
    $salt = hash("sha512", $salt3 . $salt2 . $salt . $salt2 . $salt3 . hash("sha512", $salt3 . strtotime("now - 1 day") . uniqid(rand(), true)) . uniqid(rand(), true));

    echo "Salt: ". $salt . "<br><br>";
}

Is this function good enough to make a secure salt?

Ben Johnson mk2
  • 111
  • 1
  • 4
  • 1
    Since the only requirement of salts is global uniqueness, any source of globally unique values would suffice. – Gumbo Feb 24 '14 at 13:38
  • 2
    I recommend simply using `mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)`. 16 bytes is generally enough for salts, but you can use larger values if you insist. – CodesInChaos Feb 24 '14 at 16:16

3 Answers3

6

With a language-independent approach, it's highly recommended to use well-vetted and time-tested techniques to securely hash your passwords (or any crypto-related issues, for that matters) instead of coming up with your own.

Why? Because you, by definition, is one brain. Most of the time, one brain doesn't catch its own mistakes until it's too late. Three brains is better, and four even better. Such libraries can have anywhere between tens to thousands of people working on them and/or trying to break them.

Since you're using PHP, I'd recommend using libraries that have little learning curve and they do everything for you (generating the salt, hashing, and verification) like PHPass. If you have the luxury of coding only for PHP 5.5, then you can use PHP's own API for that (check password_hash).

Finally, to answer your question directly, if you just want generate a 64 character long hex string (a gigantic 256-bit), I recommend using something like this:

$salt = bin2hex(openssl_random_pseudo_bytes(32));

Note: While 256-bit is fantastic, I think it's a bit too much for a salt. I recommend going with 128-bit (16 bytes), which will produce a 32 character long hex string.

Adi
  • 43,953
  • 16
  • 137
  • 168
3

First, as every other answer has mentioned and no doubt will mention, read How to securely hash passwords?, and perhaps also the cautionary tale of don't be a Dave.

To address the actual question, to generate a salt, simply use a well known Cryptographically secure pseudorandom number generator for however many bytes you wish of binary output. Hashing a non-cryptographically secure PRNG does not in and of itself make it a CSPRNG (see Does hashing a PRNG make it cryptographically secure?).

Whether you end up using PBKDF2, Bcrypt, or Scrypt, the password hashing process operates on binary values, so a binary salt gives you the most randomness per byte of storage, i.e. you can store 8 bytes of binary data, or a 16 byte string that encodes those same 8 bytes of binary data in hexadecimal (etc.). Every storage method other than binary takes up extra storage.

You can, of course, use other encodings - follow along with whatever well known implementation you choose.

Some examples of CSPRNGs found by a Google search on "crypto RNG [language]" include:

Note that you may want to do further research on the Perl and Ruby versions, as I didn't look for third-party confirmation, and cryptographic PRNG's are difficult to validate (see the cautionary tale of Dual_EC_DRBG in NIST SUPPLEMENTAL ITL BULLETIN FOR SEPTEMBER 2013

Anti-weakpasswords
  • 9,850
  • 2
  • 24
  • 52
-1

You're using SHA-512, which isn't recommended for salts. Rather than write your own logic to iterate it repeatedly, and maybe mess it up (which is incredibly easy to do), you should be using bcrypt (or something similar). Look at the answer to this question.

Mike Scott
  • 10,134
  • 1
  • 28
  • 35