Самый безопасный метод 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 итераций)


Если у вас есть достаточный контроль над обеими конечными точками приложения, абсолютным лучшим способом является использование PAK-Z+.

(отредактировано: рекомендуется оригинальная версия SRP но PAK-Z+ имеет доказательство безопасности.)


вот более простой способ (взятый из 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 символов длиной