使用两个单独的盐分两次散列密码并将两个散列保存在同一台服务器上是否安全

Ren*_*354 3 python security hash salt sha256

我希望我没有创建重复的问题。我试图寻找已经存在的问题,但我什么也没找到。

我已经成功地设置了一个数据库,其中包含用于登录的用户名、盐和散列密码。为了检查密码,我将生成的散列与数据库之一进行了比较,请参阅下面的代码。

password_hashed_from_user = res[0][0]
salt = res[0][1]

key_generated = hashlib.pbkdf2_hmac('sha256', password.encode('utf-8'), base64.b64decode(salt.encode('utf-8')), 100000, dklen=128)
key_encoded = base64.b64encode(key_generated).decode('utf-8')

if key_encoded != password_hashed_from_user:
    logging.debug("Password was wrong:\n{}\n{}".format(key_encoded, password_hashed_from_user))
    return "Username and/or password incorrect", False
Run Code Online (Sandbox Code Playgroud)

现在的问题是,我希望用户能够完全匿名地进行操作,这意味着我希望用户能够使用生成的令牌进行识别,而该令牌无法追溯到他的帐户

因此,我需要将令牌存储在一个单独的表中,而不是与具有凭据的表相关联。为了让用户不能作弊并且每次登录时都向服务器询问新令牌(因此充当新用户),我想根据凭据计算令牌。

所以我想,我可以有一个单独的盐并根据密码创建一个新的哈希(使用与代码示例中相同的方法)。由于密码本身并未存储在服务器上,因此如果没有用户本身的密码,就无法生成此散列。

这样,生成的令牌总是相同的,只要盐不改变。因此,我可以确保始终将特定用户标识为同一用户,而用户可以确保我无法追溯他的操作。

背景

背景是我需要创建一个投票环境,人们必须在这个环境中进行注册和身份验证,以防止重复投票,但投票结果,以及参与等不应追溯到特定用户。由于这是我研究中的一个项目,我不能只使用现有的框架/库。

现在我的问题:

在同一服务器上存储具有不同盐的相同密码的两个单独哈希值是否安全,或者重复是否可以重新创建实际密码?两种盐将与其中一个散列一起存储在一起。另一个散列将在一个单独的、不相关的表中。

在那个级别上,我总是在加密方面遇到一些困难。

SEJ*_*JPM 5

在同一服务器上存储具有不同盐的相同密码的两个单独哈希值是否安全,或者重复是否可以重新创建实际密码?

是的,这是安全的。

该语句背后的基本思想是,salt 将足够的唯一性“注入”到密码哈希可以使用的过程中,以确保两个不同的 salt 产生看起来不相关的哈希。一个真实的例子是担心两个不同的用户拥有相同的密码(但不同的盐)——这也不会泄露任何关于密码的信息,并且是引入盐的主要动机之一。

更加密的论点是,您要么假设您的散列行为像一个随机预言机——它为唯一输入产生不相关的随机输出——在这种情况下,盐的唯一性隐藏了所有输出。或者您使用较弱的假设,即您的密码散列是一个随机提取器,结合了一个伪随机函数(对于基于密码散列的密码散列来说并非不合理)以及密码输入中的密钥。在这种情况下,假设密码未知且足够随机,所有唯一的盐都将映射到与随机输出无法区分的字符串,因此无法产生有关输出的任何信息。

或者,您也可以使用Bellare、Ristenpart 和 Tessaro对密码散列安全性的定义,它基本上说“如果所述散列是好的,破解密码散列就像猜测密码一样困难”。