From here, in the code return substr(sha1(mt_rand()),0,22); what is the point of taking the sha1 value? It is appended to the password and together they are hashed using Blowfish. Why not just append the randomly generated number?

class PassHash {  
    // blowfish  
    private static $algo = '$2a';  
    // cost parameter  
    private static $cost = '$10';  
    // mainly for internal use  
    public static function unique_salt() {  
        return substr(sha1(mt_rand()),0,22);  
    // this will be used to generate a hash  
    public static function hash($password) {  
        return crypt($password,  
                    self::$algo .  
                    self::$cost .  
                    '$' . self::unique_salt());  
    // this will be used to compare a password against a hash  
    public static function check_password($hash, $password) {  
        $full_salt = substr($hash, 0, 29);  
        $new_hash = crypt($password, $full_salt);  
        return ($hash == $new_hash);  
  • 7
    Short answer: Because they don't know what they're doing. It has no beneficial effect what-so-ever. Commented Jan 10, 2013 at 17:59
  • 1
    if you're using php 5.5 use the built in functions, else use github.com/ircmaxell/password_compat (requires PHP >= 5.3.7) which offers the same API. These are designed and written by somebody who knows what he's doing. Commented Jan 10, 2013 at 18:04
  • @CodesInChaos I installed the package but am confused because I get a different hash value for the same input. Is this expected? If yes how do I check the password next time the user wants to log in?
    – Celeritas
    Commented Jan 10, 2013 at 19:44
  • your unique_salt() sucks
    – rook
    Commented Jan 10, 2013 at 19:47
  • 2
    @Celeritas - The stored salt is plain text, it is not hashed itself. You can just look for the signature $2y$10$ and the next 22 characters are the used salt, you can reuse it to calculate the new hash. In contrast to password_hash(), the function password_verify() does not create it's own salt, it uses the extracted salt from the stored hash-value. Commented Jan 11, 2013 at 21:24

2 Answers 2


They do this hashing out of a mixture of insecurity and shamanism.

The hashing has no value for actual security. Their salting is bad because mt_rand() is not sufficient to ensure uniqueness (good salts should strive to be unique, and random salts are a good way to get unique values with high probability, but it requires the use of a good random generator, in a sufficiently large space of value; and mt_rand() fails at both). Hashing the output of mt_rand() with SHA-1 gives the impression that the salt is more random than it really is; the developers must have the warm fuzzy feeling that things are safer since they "look random" to their human eyes.

Also, sprinkling hash function invocations on a given piece of code is a way to propitiate the Spirits of Cryptography. It is well-known that crypto deities look favourably upon those who use them a lot (or so many developers believe, apparently).


(Expanded to incorporate feedback from CodesInChaos)

To answer the "why" which is your question, i.e. in the general case of salt generation:

A salt is usually visible, it's not a secret. Simply using the random value might reveal some internal state information of the random number generator. A one-way hashing function hides that.

It is a poor substitute for a cryptographically secure PRNG. Such a PRNG will use one or more cryptographically secure hashed internally.

In this specific case it adds no value due to the low entropy output of PHP's mt_rand() (31 bits), and at worst may mislead. See also https://stackoverflow.com/questions/6618836/how-if-at-all-does-a-predictable-random-number-generator-get-more-secure-after

  • 2
    Due to the small amount of values mt_rand can return, undoing that SHA-1 hash is trivial. => no gain at all. Commented Jan 10, 2013 at 18:02
  • 2
    Yes that is true with PHP's mt_rand(), so it's a spectacularly poor choice for selecting a salt. I believe that the principle is still correct however. Commented Jan 10, 2013 at 18:12
  • If seeing a value from the RNG reveals anything useful about the RNG, the RNG is badly broken and must not be used anywhere near crypto (it may still be ok for numerical simulations). Commented Jan 10, 2013 at 18:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .