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