检索哈希密码的理论

时间:2015-09-24 10:03:18

标签: sqlite

这是一个理论问题,因为我已经知道以下内容:

  1. 哈希不是加密
  2. 哈希可以被打破https://crackstation.net/
  3. 我的代码不够严肃,无法在企业网站上使用
  4. 但我的问题只是关于这一切的理论。

    理论上,如果我将散列密码存储到数据库中,当用户登录时如何检查?是这么简单还是有一种标准的方法来在SQLite3中实际存储和检索密码?

    如果您可以提供一些SQLite3代码或指导从哪里开始,那将不胜感激。

    import sqlite3 
    import hashlib
    
    def encrypt_password(password):
        encrypted_pass = hashlib.sha1(password.encode('utf-8')).hexdigest()
        return encrypted_pass
    
    cemail = input("E: ")
    cpassword = input("P: ")
    connection = sqlite3.connect('/Users/Air/Desktop/users.db')
    connection.create_function('encrypt', 1, encrypt_password)
    cursor_v = connection.cursor()
    cursor_v.execute("insert into user (cemail, cpassword) values    (?,encrypt(?))", (cemail, cpassword))
    connection.commit()
    cursor_v.close()
    

2 个答案:

答案 0 :(得分:0)

在处理密码时,您需要了解至少一小部分信息:

首先,散列密码必须,这与散列函数通常的目的完全相反。

为此目的使用bcrypt或PBKDF2。 MD5 / SHA1 / 256/512对于密码来说是不够的,并且在面对基于GPU的bruteforcer(例如hashcat)时不提供真正的保护。

其次,验证密码必须处于固定时间,也就是说,无论字符串的长度如何,它们必须在同一时间完成。

字符串比较函数存在定时攻击的风险,这意味着可以通过重复向验证函数提供不同的输入来推断散列,直到显示有关散列的足够信息。

要解决此问题,请使用为您执行此操作的加密库。

如果您没有其他选择,以下伪代码应该可以帮助您了解常量算法通常如何工作(尽管您仍然应该使用库!)

def verify(hash, input):
    key = secure_random(32)
    hash = hmac_sha_512(key, hash)
    input = hmac_sha_512(key, bcrypt(input))
    results = []        

    for i, letter in input
       results.add(hash[i] === letter)

    return false not in results

第三,密码应该在整个散列中使用加密随机盐。 安全随机随机源通常来自/dev/urandom或专用于它的库。

回答的问题如果我看不到原始值,如何验证密码? - 简单,只需散列用户提供的任何内容并查看散列是否匹配数据库中的那个。但请看上面那里的巨大陷阱。

答案 1 :(得分:-1)

您无法检索散列密码,但会比较新密码是否相同。 IF HASH(new_password) == hashed_password_in_db THEN ..ok.. ELSE ..wrong password...