首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >哈希函数没有为相同的输入返回相同的输出

哈希函数没有为相同的输入返回相同的输出
EN

Stack Overflow用户
提问于 2018-12-16 23:55:41
回答 1查看 1.1K关注 0票数 2

我目前正在实现一个网站,允许用户(虚构)买卖股票。这是哈佛大学CS50计算机科学课程中的问题集9。我的程序编译、运行并通过所有检查。然而,在过去的几天里,我一直在尝试实现一个密码更改选项。

在密码更改页面上,我提示用户输入他们的旧密码。然后,用户必须输入他们想要的新密码。最后,用户必须再次确认他们的新密码。

然而,当用户输入他们的旧密码时,我的散列函数似乎输出了不同的散列,而不是他们使用该密码注册时的散列。这导致我在数据库中的散列密码和用户输入之间的比较检查总是返回false。

下面是实现密码更改的python代码。下面是实际页面的html代码,用户可以在该页面上更改其密码。

代码语言:javascript
复制
@app.route("/change", methods=["GET", "POST"])
@login_required
# PERSONAL TOUCH: <Allows user to change their password>
def change():
"""Allows user to change their password"""

if request.method == "GET":
    return render_template("change.html")

else:

    # Returns an error if Password is left blank
    if not request.form.get("originalpassword"):
        return apology("User must submit their original Password.", 400)

    elif not request.form.get("newpassword"):
        return apology("User must submit a new Password.", 400)

    elif not request.form.get("newconfirmation"):
        return apology("User must confirm their new Password", 400)

    # Hashes the Password
    Password = request.form.get("originalpassword")
    print("GIVEN PASSWORD: ", Password)
    HashedPassword = generate_password_hash(Password, method='pbkdf2:sha256', salt_length=8)

    # Returns an error if the user typed in a non-valid original password
    OldHashedPassword = db.execute("SELECT hash FROM users WHERE id = :id", id=session["user_id"])
    Old_HPW = OldHashedPassword[0]["hash"]

    print("given hash: ", HashedPassword)
    print("actual hash: ", Old_HPW)

    print("=====\n",OldHashedPassword,"\n=====\n")

    if not Old_HPW == HashedPassword:
        return apology("Submitted password is not valid.")

    # Returns an error if Password and Confirmation are not identical
    if not request.form.get("newpassword") == request.form.get("confirmpassword"):
        return apology("New Password and Confirmation must be identical.", 400)

    # Hashes the new Password
    NewPassword = request.form.get("newpassword")
    NewHashedPassword = generate_password_hash(NewPassword, method='pbkdf2:sha256', salt_length=8)

    # Insert the new Password into the database
    insertPW = db.execute("INSERT INTO users (hash) VALUES(:hash)", hash=NewHashedPassword)

    return redirect("/")

和HTML代码:

HTML Code

为了进行调试,我确实包含了一些print语句。我注册了一个新帐户,用户名为'q',密码为'q‘。然后,我试着把密码改成“qq”。在注册过程中,输入'q‘导致以下哈希:

pbkdf2:sha256:50000$sBxqbmza$e35dd4e61eb186af014e5e1ce3b73450b1361baabdd2f5f4559ad83ef0d5b45b

但是,当我在'original password‘表单字段中输入'q’时,generate_password__hash函数返回散列:

pbkdf2:sha256:50000$iAjKAPM1$f7644f34f21864062efa2f3e3f3ea0a89a8a3391a0223c1a62fa7cbaab012a71

打印语句打印的值为:

给定密码:q

给定哈希:

pbkdf2:sha256:50000$iAjKAPM1$f7644f34f21864062efa2f3e3f3ea0a89a8a3391a0223c1a62fa7cbaab012a71

实际哈希:

pbkdf2:sha256:50000$sBxqbmza$e35dd4e61eb186af014e5e1ce3b73450b1361baabdd2f5f4559ad83ef0d5b45b

很抱歉发了这么长的帖子。有谁知道是什么原因导致哈希函数为(看似)相似的输入输出不同的哈希值?

谢谢!

编辑:这个新代码似乎解决了这个问题:

NEW CODE

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-17 00:38:00

正如在这篇answer中指出的,有些库会自己生成salt,您不需要提供salt。在此库中,您只能提供盐的大小。从doc

代码语言:javascript
复制
werkzeug.security.generate_password_hash(password, method='pbkdf2:sha256', salt_length=8)

使用给定的方法散列密码,并使用给定长度的字符串进行盐运算。返回的字符串的格式包括所使用的方法,以便check_password_hash()可以检查散列。

散列字符串的格式如下所示:

代码语言:javascript
复制
method$salt$hash

如果你想存储盐,从结果中解析它。但是这个库有另一个检查/验证密码的函数;

代码语言:javascript
复制
werkzeug.security.check_password_hash(pwhash, password)

根据给定的加盐密码值和散列密码值检查密码。

所以;

在注册登录时,或更改密码时使用;

代码语言:javascript
复制
generate_password_hash

要验证密码,请使用;

代码语言:javascript
复制
check_password_hash
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53803875

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档