Самый безопасный метод Python для хранения и извлечения паролей из базы данных
глядя на хранение имен пользователей и паролей в базе данных, и мне интересно, что самый безопасный способ сделать это. Я знаю, что мне нужно где-то использовать соль, но я не уверен, как ее безопасно генерировать или как применять ее для шифрования пароля. Некоторые примеры кода будет принята с благодарностью. Спасибо.
5 ответов
хранить пароль + соль в виде хэша и соли. Посмотрите, как это делает Django:основные документы и источник.
В БД они хранят <type of hash>$<salt>$<hash>
в одном поле char. Вы также можете хранить эти три части в отдельных полях.
функция для установки пароля:
def set_password(self, raw_password):
import random
algo = 'sha1'
salt = get_hexdigest(algo, str(random.random()), str(random.random()))[:5]
hsh = get_hexdigest(algo, salt, raw_password)
self.password = '%s$%s$%s' % (algo, salt, hsh)
get_hexdigest - это просто тонкая оболочка вокруг некоторых алгоритмов хэширования. Для этого вы можете использовать hashlib. Что-то вроде hashlib.sha1('%s%s' % (salt, hash)).hexdigest()
и функции для проверки пароля:
def check_password(raw_password, enc_password):
"""
Returns a boolean of whether the raw_password was correct. Handles
encryption formats behind the scenes.
"""
algo, salt, hsh = enc_password.split('$')
return hsh == get_hexdigest(algo, salt, raw_password)
Я думаю, что лучше всего использовать пакет, посвященный хэшированию паролей для этого, как passlib:http://packages.python.org/passlib/ по причинам, как я объяснил здесь:https://stackoverflow.com/a/10948614/893857
Я ответил на это здесь:https://stackoverflow.com/a/18488878/1661689, а также @Koffie.
Я не знаю, как подчеркнуть достаточно, что принятый ответ не является безопасным. Это лучше, чем обычный текст, и лучше, чем несоленый хэш, но это все равно крайне уязвимыми словарь и даже грубой силы атак. Вместо этого, пожалуйста используйте медленный KDF как bcrypt (или по крайней мере PBKDF2 с 10 000 итераций)
вот более простой способ (взятый из effbot), при условии, что пароли с длиной больше 8 не будет проблемой*:
import crypt
import random, string
def getsalt(chars = string.letters + string.digits):
# generate a random 2-character 'salt'
return random.choice(chars) + random.choice(chars)
для генерации пароля:
crypt.crypt("password", getsalt())
*: пароль длиной более 8 обрывается справа до 8 символов длиной