Подтвердить что ты не робот

Самый безопасный метод Python для хранения и извлечения паролей из базы данных

Ищете, чтобы хранить имена пользователей и пароли в базе данных, и мне интересно, какой самый безопасный способ сделать это. Я знаю, что мне нужно использовать соль где-нибудь, но я не уверен, как ее безопасно создать или как ее применить для шифрования пароля. Некоторый пример кода Python был бы весьма полезен. Спасибо.

4b9b3361

Ответ 1

Сохраните пароль + соль как хэш и соль. Взгляните на то, как Django делает это: основные документы и source. В db они хранят <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)

Ответ 2

Я думаю, что лучше использовать пакет, предназначенный для хэширования паролей для этого, например passlib: http://packages.python.org/passlib/ по причинам, как я объяснил здесь: fooobar.com/questions/108171/...

Ответ 3

Я ответил на это здесь: fooobar.com/questions/108171/..., а также @Koffie.

Я не знаю, как подчеркнуть, что принятый ответ НЕ безопасен. Это лучше, чем обычный текст, и лучше, чем несостоявшийся хеш, но он по-прежнему чрезвычайно уязвим к словарю и даже атакам с использованием грубой силы. Вместо этого используйте SLOW KDF, например, bcrypt (или, по крайней мере, PBKDF2 с 10000 итерациями)

Ответ 4

Если у вас достаточно контроля над обеими оконечными точками приложения, самым лучшим способом является SRP.

Ответ 5

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