如何从数据库中检索密码 [英] How to retrieve passwords from a database

查看:135
本文介绍了如何从数据库中检索密码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为我的Web应用程序构建一个注册系统,其中用户提供用户名和密码。此数据存储在 postgresql 数据库中。我正在使用bcrypt生成用户输入密码的盐腌哈希,如下所示:

I am building a registration system for my web application wherein users provide a username and a password. This data is stored in a postgresql database. I am using bcrypt to generate a salted hash of the user entered password as follows

import bcrypt
hashed = bcrypt.hashpw(PasswordFromWebForm.encode('UTF-8'), bcrypt.gensalt()) 

一个看起来像这样的加盐密码- b'$ 2b $ 12 $ GskbcRCMFHGuXumrNt3FLO'

This creates a salted password that looks something like this - b'$2b$12$GskbcRCMFHGuXumrNt3FLO'

我正在存储此值在 postgresql 数据库中。接下来,当用户尝试登录系统时,我想验证其凭据。为此,我打算执行以下操作-

I am storing this value in a postgresql database. Next, when a user tries to login to the system, I want to verify his/her credentials. To do this, I intend to do something along the lines of -

import psycopg2
conn = psycopg2.connect("dbname=test user=me")
cur = conn.cursor()

saltedpassword = cur.execute("SELECT saltedpassword FROM test WHERE loginid = %s", (LoginIDFromWebForm,))

if bcrypt.hashpw(PasswordFromWebForm.encode('UTF-8'), saltedpassword) == saltedpassword:
    print("Success")

这不起作用。它将引发以下 TypeError:必须先对Unicode对象进行编码,然后再进行散列错误。

This does not work. It throws the following TypeError: Unicode-objects must be encoded before hashing error.

我怀疑这个错误是因为变量 saltedpassword 将值存储为这样的字符串,例如 b'$ 2b $ 12 $ GskbcRCMFHGuXumrNt3FLO' 而不是普通的 b'$ 2b $ 12 $ GskbcRCMFHGuXumrNt3FLO'(请注意引号盐腌的密码)

I suspect that this error is because the variable saltedpassword stores the value as a string like this "b'$2b$12$GskbcRCMFHGuXumrNt3FLO'" instead of just plain b'$2b$12$GskbcRCMFHGuXumrNt3FLO' (Notice the quotes enclosing the salted password in the former)

如何解决此问题?将盐腌的哈希密码存储在数据库中的最佳方法是什么?在需要进行验证时,如何去检索它?很抱歉,这个问题已经很久了-请帮忙。

How do I get around this problem? What is the best way to store the salted hashed password in a database and how do I go about retrieving it when needed for verification? Apologies for the rather longish question - please help.

推荐答案

psycopg2 存储Unicode 文本,您必须先解码加盐密码,然后再将其插入数据库:

psycopg2 stores Unicode text, you must decode the salted password before inserting into the database:

 cur.execute("INSERT INTO test VALUES (%s, %s)",
             (LoginIDFromWebForm,  saltedpassword.decode('ascii')))

这样可以防止插入 str()转换(这会给您 b'....'

This prevents the str() conversion being inserted instead (giving you "b'....'" in the database).

接下来,当查询 saltedpassword 不是字符串时,因为 cursor。 execute()不返回结果;它会返回 None

Next, when querying saltedpassword is not a string, because cursor.execute() does not return the results; it returns None instead.

您需要获取结果行

cur.execute("SELECT saltedpassword FROM test WHERE loginid = %s", (LoginIDFromWebForm,))
row = cur.fetchone()
if not row:
    # No such login ID, handle accordingly
saltedpassword =  row[0].encode('ascii')

由于行包含Unicode文本,因此您需要先将其编码为字节串,然后再将其传递给 bcrypt 。您还想使用 bcrypt.checkpw()函数检查密码:

Since rows contain Unicode text, you need to first encode to a bytestring before passing it to bcrypt. You also want to use the bcrypt.checkpw() function to check the password:

if bcrypt.checkpw(PasswordFromWebForm.encode('UTF-8'), saltedpassword):
    print("Success")

bcrypt.checkpw()避免定时攻击比较字符串时,您的代码容易受到攻击。

bcrypt.checkpw() avoids timing attacks when comparing strings, something your code is vulnerable to.

这篇关于如何从数据库中检索密码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆