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. – CodesInChaos Jan 10 '13 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. – CodesInChaos Jan 10 '13 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 Jan 10 '13 at 19:44
  • your unique_salt() sucks – rook Jan 10 '13 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. – martinstoeckli Jan 11 '13 at 21:24

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. – CodesInChaos Jan 10 '13 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. – mr.spuratic Jan 10 '13 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). – Gilles Jan 10 '13 at 18:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.