Username as password salt

Is there any reason why one should not use the username as the password salt? Storing md5( username . password ) instead of md5( password ) in the password column.

It seems like a very simple idea, so I’m sure there’s a good reason why it’s not in popular use. Hopefully somebody can tell me that reason! :)

9 thoughts on “Username as password salt

  1. … only that the username is frequently a known quantity, particularly for users such as ‘admin’ or ‘root’ that you might reasonably want to attack. Since the point of salt is to eliminate pre-calculated hashes being used in a dictionary attack, it doesn’t help when a set of pre-calculated hashes can be created with the salt ‘admin’ or ‘root’.

  2. An excellent point Alex, I knew you’d chime in with something useful! :)

    So simply combining the two would not provide adequate protection against rainbow attacks. Very true. But the two combined with a known constant, such as the site URL, would presumably overcome this issue. Each record would be individually unique, and the whole namespace would also be globally unique.

  3. It’s not devoid of use, but As Alex pointed out – it’s probably better to keep that known constant hidden and treat it like a password in itself. That way nobody else can build their own hash database (easily) by just starting from MD5(salt . ‘a’) .. MD5(salt . ‘b’) etc.

    FWIW, the largest hash database I know of is Gdata (http://gdataonline.com/). Presumably from their homepage they have 670M hashes – which is just a bit less than 64^5.

    The storage cost for 64^5 is 4G just for the hashes – and for 64^6 it’s 256G, so it starts to get expensive quickly.

  4. @Morgan Tocker: Thanks for chiming in.

    It’s true that you could build your own hash database, but would it not be prohibitively expensive (time and disk wise)? I thought the beauty of rainbow table attacks is that you precompute the rainbow table once, then you can store it indefinitely. Whereas I haven’t heard the argument that the principle of hashing in itself is flawed.

    I understood that passwords were stored as salted hashes so that a rainbow table would be useless. In effect, an attacker would need to generate a new rainbow table for every user, which would be prohibitively expensive.

    I think I’ll go with something like md5( username . password . domain ). It would be possible from that data to break the passwords, but it would require a *huge* amount of work.

  5. You are correct that double salting the password with a private salt(username) and a public salt(domain) would require a new brute force attack for each password. However, you are better off using unknown/unknowable salts.

    If the attacker doesn’t know any of the three, their brute force would look like:
    {guess}{guess}{guess}
    {guess1}{guess}{guess}
    .
    .
    {guess}{guess1}{guess}…

    If the attacker does know one or more of the salts:
    salt{guess}{guess} or salt{guess}salt
    salt{guess1}{guess} or salt{guess1}salt…

    So you lower the amount of work they would need to do to break any one particular password by using salts they could know.

    Here’s what I do:
    I generated a very long random string using every kind of character. I keep it in my php scripts and that is the same for all my passwords.
    Then I add another row to my users table to store a private salt for each user, which is generated and stored automatically by PHP when the user registers.

    When a user logs in I take the username they entered, get the private salt with it, add the public salt, hash it and check against the stored password. A hacker would have to compromise both the php script AND the database to get both the salts.

    Finally, this is all mostly useless if you’re using md5 which has been broken in oh so many ways(though not completely). I would use something like whirlpool or sha-1[if you trust the government ;)]

    • @Tes – Love your idea of keeping an app-salt to add additional protection against database compromise through injection attacks ;-) though I reckon that any server compromise is more likely to be the web server than the db, since the latter are usually not publicly accessible (nor through a firewall pinhole).

      Your idea also made me think of also hashing the user name (optionally using the app salt). Once a record is compromised, a brute force attack is required for both fields (emails as user names would make them even harder to break given their length).

      A compromise of the hashed passwords without their respective salts doesn’t seem a likely scenario as a brute force attack vector; this means that, technically speaking, the user name / email is a good salt candidate in this respect even though intuitively a hidden salt is better. Depending on the hash algorithm, building a rainbow table may take a long time, even when all salts are known; this service would have to be extremely popular to be a viable attack target ;-)

      So here’s the catch; when the user decides to change their password, having a private salt gives you the advantage of being able to regenerate it (causing the hash to change even if the new password is the same).

  6. Pingback: Benjamin Carl - PHP continuous-integration test-driven-development qualitätssicherung software-architektur - » Salt’n’Pepper – Username als Pepper zum Salt für den Hash

  7. Pingback: Salt’n’Pepper – Username als Pepper zum Salt | PHPFlüsterer

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>