这是一个理论问题,因为我已经知道以下内容:
但我的问题只是关于这一切的理论。
理论上,如果我将散列密码存储到数据库中,当用户登录时如何检查?是这么简单还是有一种标准的方法来在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()
答案 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...
。