【问题标题】:How can I disable concatenation when using hashlib's update method?使用 hashlib 的更新方法时如何禁用连接?
【发布时间】:2020-02-06 19:33:28
【问题描述】:

我已经编写了一个使用 hashlib 散列密码的方法。 我允许用户通过 POST 方法发送密码,该方法由 Flask 接收,然后对密码进行哈希处理,以便可以根据存储的 var 检查哈希值是否相同。

当第一次发送正确或错误的密码时,它都很好用。 但是,如果用户在第一次 POST 时发送了错误的密码,然后使用正确的密码再次尝试,则会失败。 (如果第一次尝试成功并且用户继续尝试,也可以将其视为失败,但我现在不在乎。)

I was able to narrow the problem down to hashlibs update function

hash.update(arg) 使用字符串 arg 更新哈希对象。重复调用等效于连接所有参数的单个调用: m.update(a); m.update(b) 等价于 m.update(a+b)。

我想知道如何在重复调用时禁用串联。 这是否是一个 hacky 解决方法并不重要。

这是我的代码,以防有用:

h = hashlib.sha256()
VALID_USERNAME = 'admin'
VALID_PASSW_HASH = "210ce034be6d826a451a4261d70494148c5d7101627335ccacf8e00a711bcc5d"

@app.route('/api/queue/auth', methods=['POST'])
def auth():
    username = request.json.get('username')
    password = request.json.get('password')
    if bool(username) is False or bool(password) is False:
        return "\nPlease fill in both fields.\n", 400
    passwordBytes = password.encode(encoding='UTF-8',errors='strict')
    h.update(passwordBytes)
    if h.hexdigest() != VALID_PASSW_HASH or username != VALID_USERNAME:
        return "\nPlease check your username and password, and try again.\n", 401
    r.set('auth', 'true')
    return "Access Granted.\n", 200

补充说明:

  • “r.set”行(在最后一行之上)只是因为它后来对 Redis 做了一些事情。
  • 我检查了 passwordBytes 在提供相同密码时总是返回相同的编码(它是确定性的)
  • 我还检查了如果在第一次尝试或另一次尝试中提供了相同的密码,h.hexdigest() 会返回不同的内容。所以考虑到这两点,我们可以确定问题出在 h.update() 上,可能是因为 concatenation 特性。

【问题讨论】:

  • 此方案不安全。请使用正确的密码哈希,而不是消息摘要函数。 Werkzueg 的密码哈希是安全的。

标签: python cryptography sha256 hashlib cryptographic-hash-function


【解决方案1】:

只需将第一行移出全局范围到auth() 函数中:

VALID_USERNAME = 'admin'
VALID_PASSW_HASH = "210ce034be6d826a451a4261d70494148c5d7101627335ccacf8e00a711bcc5d"

@app.route('/api/queue/auth', methods=['POST'])
def auth():
    username = request.json.get('username')
    password = request.json.get('password')
    if bool(username) is False or bool(password) is False:
        return "\nPlease fill in both fields.\n", 400
    passwordBytes = password.encode(encoding='UTF-8',errors='strict')
    h = hashlib.sha256()
    h.update(passwordBytes)
    if h.hexdigest() != VALID_PASSW_HASH or username != VALID_USERNAME:
        return "\nPlease check your username and password, and try again.\n", 401
    r.set('auth', 'true')
    return "Access Granted.\n", 200

或者更好的是,将密码的散列重构为不同的函数:

VALID_USERNAME = 'admin'
VALID_PASSW_HASH = "210ce034be6d826a451a4261d70494148c5d7101627335ccacf8e00a711bcc5d"

def hash_password(password):
    passwordBytes = password.encode(encoding='UTF-8',errors='strict')
    h = hashlib.sha256()
    h.update(passwordBytes)
    return h.hexdigest()


@app.route('/api/queue/auth', methods=['POST'])
def auth():
    username = request.json.get('username')
    password = request.json.get('password')
    if bool(username) is False or bool(password) is False:
        return "\nPlease fill in both fields.\n", 400
    if hash_password(password) != VALID_PASSW_HASH or username != VALID_USERNAME:
        return "\nPlease check your username and password, and try again.\n", 401
    r.set('auth', 'true')
    return "Access Granted.\n", 200

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-07
    • 1970-01-01
    相关资源
    最近更新 更多