java 散列和加盐值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2969787/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hashing and salting values
提问by Avanst
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.
我正在开发一个内部验证用户的小型网络应用程序。一旦用户通过身份验证,我的 Web 应用程序就会将一些信息(例如用户 ID 和人员姓名)传递给第三方 Web 应用程序。第三方开发人员建议我们对值进行散列和加盐。
Forgive my ignorance, but what exactly does that mean?
原谅我的无知,但这到底是什么意思?
I am writing the app in Java. So what I am planning 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.
我正在用 Java 编写应用程序。所以我打算做的是散列用户 ID、人名和一些 Math.random() 值作为使用 Apache Commons Digest Utils SHA512 的盐,并将散列字符串与用户 ID 和人名一起传递。
Is that the standard practice? I should be passing the third party the salt as well correct?
这是标准做法吗?我也应该将盐传递给第三方,对吗?
回答by Marc
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.
为了安全登录第三方网站,可以发送用户 ID、加盐哈希(从上面)和你使用的盐(如果没有给出)。根据该网站存储密码的方式,您可以为自己生成盐,也可以向其索要盐。
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.
一种选择是先将 UserID 发送到网站,然后让它用盐进行响应,然后再将其发送hash(password+salt))回网站。
回答by Amy B
In Java you can do something like:
在 Java 中,您可以执行以下操作:
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.
然后密码不可读,即使黑客窃取了您的数据库。
回答by Chris Dutrow
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.
请注意,关于如何处理 Salt 存在一些错误信息。储存盐是正常的。每个密码都应该有自己的盐,并与它一起以纯文本形式存储。它旨在让已经窃取您的散列密码数据库的人更难使用预先计算的散列表对其进行解密。
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.
至于您是否应该向第三方发送盐,我必须了解更多信息。在身份验证期间获取客户端提供的密码,对其进行散列并将其与预先散列的版本进行比较的任何人都需要盐,以便客户端提供的用于身份验证的密码可以与以前完全相同。
回答by dimo414
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.
您在程序中对用户进行身份验证(几个答案似乎正在解决这个问题,是的,您应该将用户密码存储为加盐哈希,但这是一个完整的“另一个问题”),然后在对他们进行身份验证时传递一些信息到这个第三方应用程序。现在,这取决于这个应用程序究竟应该做什么/知道什么。例如,如果它需要知道用户 ID,那么您不能在提交之前对其进行哈希/加盐处理,因为应用程序将永远无法取回原始用户 ID。另一方面,如果应用程序只需要某种标识符来识别请求,并且散列 userID+userName 只是一个建议,那么这确实有意义,您基本上是为要使用的第三方应用程序,基本上用作会话密钥。
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.
所以就像我说的,看看你是否能找到一些例子,或者即使你想在这里发布有关相关应用程序的更多信息,我们可以自己看看。
回答by Kevin
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.
一旦用户通过身份验证,我的 Web 应用程序就会将一些信息(例如用户 ID 和人员姓名)传递给第三方 Web 应用程序。第三方开发人员建议我们对值进行散列和加盐。
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
我打算做的是散列用户 ID、人名和一些 Math.random() 值作为盐
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
使用 SHA-256 或 SHA-512 很好,这是NIST 推荐的
回答by NoozNooz42
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
http://en.wikipedia.org/wiki/Rainbow_table
Instead of just doing a hash(a) and storing the hash:
而不是仅仅做一个散列(a)并存储散列:
:460526e74fd6a25b525e642db2f756a4:
you do hash(a + salt)and you store the hash and the salt (the salt can be randomly picked):
你做hash(a + salt)并存储散列和盐(盐可以随机选择):
:cdd5bc3f05f6a76f6c82af728b2c555c:346884e6e35be:

