开发者

Hashing and salting values

开发者 https://www.devze.com 2023-01-02 09:42 出处:网络
I am developing a small web app that internally authenticates users. Once the user is authenticated my web app then passes some information such as userID and Person\'s name to a third party web appli

I am developing a small web app that internally authenticates users. Once the user is authenticated my web app then passes some information such as userID and Person's name to a third party web application. The third party developer is suggesting that we hash and salt the values.

Forgive my ignorance, but what exactly does that mean?

I am writing the app in Java. So what I am p开发者_如何学运维lanning on doing is hashing the userID, Person's name, and some Math.random() value as the salt with Apache Commons Digest Utils SHA512 and passing that hashed string along with the userID and person's name.

Is that the standard practice? I should be passing the third party the salt as well correct?


A salt is normally used for storing hashes of passwords safely. Hashing a password for storage or communication (such that it can't be read by others) is vulnerable for decoding by using rainbow tables. Now, when you add a random string to the password, but store the string with the hash, this becomes much harder. Calculating this new hash looks like:

hash(password + salt)

or even

hash(hash(password) + salt)

To safely log into a third party website, can send the UserID, salted hash (from above) and the salt that you used (if it is not given). Depending on how that website stored its passwords, you can generate the salt for yourself or you can ask for a salt from it.

One option is to send the UserID first to the website, then let it respond with the salt, and then send the hash(password+salt)) back to the website.


In Java you can do something like:

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.RandomStringUtils;

/**
 * SHA1-hash the password with the user's salt.
 *
 * @param password
 */
public void setPassword(String password)
{
    if (password.equals(this.password))
    {
        return;
    }

    if (passwordSalt == null || passwordSalt.equals(""))
    {
        passwordSalt = RandomStringUtils.randomAscii(20);
    }

    this.password = DigestUtils.shaHex(password + passwordSalt);
}

/**
 * Check if a given password is correct.
 *
 * @param givenPassword
 * @return True is correct, else false.
 */
public boolean checkPassword(String givenPassword)
{
    return (password.equals(DigestUtils.shaHex(givenPassword + passwordSalt)));
}

Then the password is not readable, even if a hacker steals your DB.


Just a heads up, there is some misinformation out there on what to do with the Salt. It IS ok and normal to store the salt. Each password should have its own salt that is stored in plain text along with it. It is meant to make it a lot harder for someone who has already stolen your hashed password database to de-crypt it using a pre-calculated hash table.

As far as if you should be sending the third party the salt, I'd have to have a little more information. Whoever is taking the client-supplied password during authentication, hashing it and comparing it against the pre-hashed version needs the salt so that the password that the client supplies for authentication can be hashed exactly the same as it was before.


Once the user is authenticated my web app then passes some information such as userID and Person's name to a third party web application. The third party developer is suggesting that we hash and salt the values.

That doesn't sound right. Hashes are one-way operations. You can't take the result of a hash and divine the plain text from it

What I am planning on doing is hashing the userID, Person's name, and some Math.random() value as the salt

For any given plaintext, you need to use the same salt or else the resulting hash will be different. So if you're going to use a random or generated salt, you need to store it along with the password hash.

Using SHA-256 or SHA-512 is fine and is what NIST recommends


I would see if you can't find more information or some examples from this third party app you're working with. What you're describing does not seem like common practice, and honestly doesn't even make that much sense based off what you've said.

You authenticate the user in your program (several answers seem to be addressing this issue, and yes, you should be storing your users passwords as salted hashes, but that's a whole 'nother issue) and then, upon authenticating them, are passing some information to this third party app. Now, it depends on what exactly this app is supposed to do / know. If it needs to know the userID, for instance, then you can't hash/salt it before submitting it, because the app will never be able to get the original userID back. On the other hand, if the app simply needs some sort of identifier to recognize requests, and hashing userID+userName is simply a suggestion, then this does make sense, you're basically generating a user-unique but un-decodable string for the third party app to use, basically as a session key.

If that second route is what they're trying to have you do, it's a somewhat odd (and not terribly secure) way of dealing with requests, but seems alright to me.

So like I said, see if you can find some examples, or even if you want post more information about the app in question here, and we can take a look ourselves.


The whole point of a salt is to make attacks using what are called "rainbow tables" infeasible (from a probabilistic point of view: if you take a sufficiently big hash, then it becomes effectively impossible to precompute the rainbow tables).

http://en.wikipedia.org/wiki/Rainbow_table

Instead of just doing a hash(a) and storing the hash:

:460526e74fd6a25b525e642db2f756a4:

you do hash(a + salt) and you store the hash and the salt (the salt can be randomly picked):

:cdd5bc3f05f6a76f6c82af728b2c555c:346884e6e35be:
0

精彩评论

暂无评论...
验证码 换一张
取 消