У меня есть друг, назовем его Сяо Ван. Несколько дней назад Сяо Ван пошел на собеседование;
Интервьюер спросил: Как хранить пароли в базе данных?
сцена: Сяо Ван — заявитель, а г-н Чжан — интервьюер. Собеседование в основном посвящено хранению паролей и соответствующим технологиям безопасности.
Г-н Чжан: «Здравствуйте, Сяо Ван. Я видел, что вы упомянули в своем резюме, что имеете некоторое представление о безопасности паролей. Можете ли вы вкратце рассказать о том, какие меры следует предпринять, когда мы хотим хранить пароли пользователей?»
Сяо Ван: «Конечно, пароль — это конфиденциальная информация, поэтому нам необходимо его зашифровать, чтобы обеспечить его защиту в базе данных».
Г-н Чжан: «Шифрование? Вы имеете в виду, что пароль необходимо шифровать при его хранении? Можете ли вы это объяснить?»
Сяо Ван: «Да, мы можем использовать алгоритмы шифрования, такие как AES, чтобы зашифровать пароль и сохранить его в базе данных».
Г-н Чжан: «Вы уверены, что хотите его зашифровать? Если мы зашифруем пароль, системе потребуется расшифровать пароль для сравнения при проверке входа пользователя. Это безопасно?»
Сяо Ван: «Хм… Я думаю, может быть, пароль не стоит расшифровывать. Может быть, хеширование уместнее?»
Г-н Чжан: Да. Обычно мы не шифруем пароли, а хешируем их, потому что хэши необратимы. Знаете, почему мы это делаем?
Сяо Ван: «Я думаю, это сделано для предотвращения утечки пароля. Даже если база данных будет взломана, хакер не сможет напрямую получить пароль в виде открытого текста».
Г-н Чжан: Да. Но одной хэш-обработки недостаточно. Знаете ли вы об атаке с помощью радужной таблицы?
Сяо Ван: «Радужная таблица? Я слышал о ней, похоже, она связана со взломом хеш-значений?»
Г-н Чжан: «Да, радужная таблица — это заранее рассчитанная таблица хеш-значений. Злоумышленник может использовать ее для сопоставления хэш-значения в базе данных и поиска соответствующего открытого текстового пароля. Таким образом, просто полагаться на хэш-значение недостаточно. .Знаете, можем ли мы еще что-нибудь сделать, чтобы предотвратить это нападение?»
Сяо Ван: «Добавление соли? Мы можем сгенерировать случайное значение соли для каждого пароля, а затем хэшировать его».
Г-н Чжан: «Да, добавление соли является важной мерой для предотвращения атак по радужным таблицам. Добавляя уникальные случайные соли, мы можем значительно повысить сложность взлома. Можете ли вы привести пример того, какой алгоритм хэширования вы будете использовать?»
Сяо Ван: «Раньше наша компания использовала SHA-256 для хеширования паролей. Я слышал, что он более безопасен, чем MD5».
Г-н Чжан: «SHA-256 действительно намного безопаснее, чем MD5, но на самом деле существуют более подходящие варианты хеширования паролей. Вы слышали об Argon2?»
Сяо Ван: «Argon2 — это алгоритм, разработанный специально для хеширования паролей и получивший награду конкурса криптозоологии 2015 года. Он может устанавливать использование памяти и количество итераций, что делает его более эффективным в борьбе с грубым взломом. По сравнению с SHA-256 , Argon2 устойчив к параллельным атакам на современное оборудование».
Г-н Чжан: «Звучит очень убедительно. Тогда почему бы нам просто не использовать SHA-256? Разве он не очень широко используется?»
Сяо Ван: «SHA-256 — это алгоритм хеширования общего назначения, в основном используемый для проверки целостности данных, таких как блокчейн и цифровые подписи. Однако его применение в криптографии не так хорошо, как специализированные хэши паролей, такие как алгоритм хеширования паролей Argon2. чтобы справиться с проблемами грубой силы и временной сложности, а Argon2 может обеспечить лучшую защиту».
Г-н Чжан сказал в своем сердце: «Молодой человек неплох... он талант».
Сегодня у нас будет углубленный разговор, основанный на опыте собеседования моего друга Сяо Вана: Как хранить пароли в базе данных?
Была ли у вас когда-нибудь такая путаница?:Почему система всегда просит нас создать новый пароль вместо того, чтобы сообщить нам исходный пароль, когда мы забываем пароль для входа в учетную запись и нажимаем «Забыли пароль»?
Вам это может показаться немного неудобным, потому что иногда вы просто хотите знать старый пароль и не хотите думать о новом. Однако, когда вы узнаете больше о программировании, вы обнаружите, что существуют весьма разумные соображения безопасности.
В этой статье мы подробно обсудим эту проблему и поможем студентам, которые были или не уверены в этой проблеме, понять ее причины.
Предположим, что пользователь регистрирует учетную запись на вашем сайте, например. xw@qq.com
,и установите пароль на abc654321
。Самый прямой способ — хранить пароль пользователя в открытом виде в базе данных.:
username password
xw@qq.com abc654321
Этот метод прост и понятен,Но существуют огромные риски для безопасности。Если хакер получил доступ к вашей базе данных,Он не только может увидеть пароль пользователя,Он также может легко угадать ту же учетную запись и пароль пользователя на других веб-сайтах.。фактически,Многие пользователи используют одну и ту же комбинацию адреса электронной почты и пароля на нескольких веб-сайтах.,Это позволяет хакерам скомпрометировать веб-сайт путем,Получите информацию о пользователе с нескольких веб-сайтов. поэтому,Хранение паролей в открытом виде практически не обеспечивает защиты.
Чтобы устранить риски, вызванные хранением обычного текста,Разработчики часто преобразуют пароли в необратимыеХэш-значение,Затем сохраните Хэш-значение в базе данных. Например:
username password
xw@qq.com 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
В этом примере пароль abc654321
передается через алгоритм хеширования (например, SHA-1 или SHA-256) в необратимую строку символов. Даже если хакер получит это значение хеш-функции, он не сможет напрямую вывести исходный пароль из значения хеш-функции.
Защитите конфиденциальность пользователей:Если систему можно восстановитьили Посмотреть исходный пароль,Таким образом,Сама система будет иметь текстовую копию пароля пользователя. Это значительно увеличит риск компрометации пароля.
Предотвращение неправомерного использования после утечки данных:Даже если хакер взломает базу данных,Хэш-значение кто получил пароль,Также невозможно обратно вычислить исходный пароль посредством этих Хэш-значений. Такая конструкция значительно снижает риск кражи пароля.
Однако,Алгоритм Хэша Не совсем оборонительный。Хотя Хэшэто односторонний,Но хакеры могут взломать его грубой силой.илииспользоватьзаранее рассчитанный Хэш-значениеповерхность(Например彩虹поверхность)Выполнить вывод。вот почемуЧем быстрее рассчитывается алгоритм хеширования, тем менее он пригоден для хранения паролей.。Например,SHA-1 Расчет происходит очень быстро, поэтому он не подходит для прямого использования при хешировании паролей.
Хеширование пароля с использованием SHA-256
import hashlib
def hash_password_sha256(password: str) -> str:
# использовать SHA-256 Алгоритм Хэша
sha_signature = hashlib.sha256(password.encode()).hexdigest()
return sha_signature
# Пример
password = "abc654321"
hashed_password = hash_password_sha256(password)
print("SHA-256 Хэш-значение:", hashed_password)
Хотя этот метод более безопасен, чем хранение паролей в открытом виде, его все же недостаточно, чтобы противостоять современным атакам методом перебора.
Атака по радужной таблице — это метод, который пытается быстро взломать хешированные пароли путем предварительного вычисления большого количества общих паролей и их хешей. Злоумышленник может использовать эти таблицы для быстрого поиска, сопоставления хеш-значения в базе данных и получения пароля.
Моделирование атаки по радужной таблице
import hashlib
# Простая имитация общего словаря паролей
common_passwords = ["123456", "password", "abc123", "qwerty", "letmein"]
# Хэш-значение (то есть имитация радужной таблицы), используемое для хранения общих паролей.
rainbow_table = {}
# Создайте радужный стол (использовать SHA-256 Алгоритм Хэша)
def create_rainbow_table():
for password in common_passwords:
hashed_password = hashlib.sha256(password.encode()).hexdigest()
rainbow_table[hashed_password] = password
print("Генерация радужной таблицыуспех!")
# Имитация взлома злоумышленником пароля Хэш через радужную таблицу
def crack_password(hashed_password):
# Попробуйте использовать радужную таблицу, чтобы найти оригинальный пароль.
if hashed_password in rainbow_table:
return rainbow_table[hashed_password]
else:
return None
# Создайте радужный стол
create_rainbow_table()
# Имитировать пароли Хэша, хранящиеся в базе данных
stored_hashed_password = hashlib.sha256("abc123".encode()).hexdigest()
print("Сохраненный пароль Хэша:", stored_hashed_password)
# Попытка взломать сохраненный пароль Хэша через радужную таблицу.
cracked_password = crack_password(stored_hashed_password)
if cracked_password:
print(f"Пароль взломан: {cracked_password}")
else:
print("Невозможно взломать пароль")
Генерация радужной таблицы:我们首先创建Понятно一个简单的彩虹поверхность,Хэш-значение, содержащее общие пароли. Настоящая радужная таблица будет очень большой.,Содержит миллионы и более общих паролей и их Хэш-значение.
симуляция атаки:我们尝试通过彩虹поверхность匹配数据库中存储的Хэшпароль。Если соответствующий найден Хэш-значение,Мы можем восстановить исходный пароль.
Радужный стол Хотя работает,Но есть ограничения,特别是当пароль存储中использовать ПонятноС сольютехническое время:
С сольюзащита:每个пароль都有独立的随机盐,Даже если радужная таблица содержит тот же пароль,И не может соответствовать Хэш-значение. так,Даже если злоумышленник получит базу данных,Им также необходимо взломать каждый пароль один за другим.
bcrypt и Другой «медленный» алгоритм Хэша:картина bcrypt、PBKDF2 Такой алгоритм хеширования паролей не только автоматически использует соль, но и еще больше увеличивает сложность взлома за счет увеличения времени вычислений.
С здесь солью,Это не поваренная соль, которую мы едим,С солью,По сути, это понятие в программировании,Используется для повышения безопасности паролей. чтобы понять это,Вы можете представить себе сцену из нашей повседневной жизни.
Предположим, вы любите пить кофе, и всем тоже нравится пить кофе. Кому-то нравится добавлять сахар, кому-то – нет. Теперь, если бы я дал вам ту же самую чашку черного кофе без сахара, вы могли бы с первого глотка сказать, что это чистый кофе и по вкусу точно такой же, как кофе в чьей-то чашке. То же самое верно и для хакеров при взломе паролей. Если у каждого метода хранения паролей является прямое хэширование пароля, хакеры могут взломать ваш пароль, сопоставив множество «обычных черных кофе» (простых паролей).
С солью,Это все равно, что добавить в кофе немного «уникальной специи».,Такие как сахар и сливки,Или даже другие начинки, которые вам нравятся. так,Даже если ингредиенты кофе у двух человек одинаковые (например, пароль одинаковый),Но каждый добавляет в него разные ингредиенты.,В результате вкус совершенно другой.
в хранилище паролей,«Соль» – это уникальная приправа. каждый раз, когда ты устанавливаешь пароль,Система добавляет к вашему паролю «соль» (случайно сгенерированную строку символов). Когда система сохраняет ваш пароль,它保存的是пароль加上盐后的一串Хэш-значение(类似你加Понятно调料后咖啡的味道)。Таким образом, даже если хакер узнает, что чужой пароль — «123456», поскольку вы добавили разные соли, он все равно не сможет выяснить, какой пароль вы использовали при его взломе.。
Предположим, что вы и ваш друг установили один и тот же пароль «пароль». Без соли хакер, получивший хэш пароля человека, может сразу сделать вывод, что ваш пароль и пароли всех остальных — это «пароли».
Но если добавить соль,Эквивалент пароля каждого человека больше не является простым «паролем».,Вместо этого он становится «salt1+пароль» (вы добавили немного соли 1) и «salt2+пароль» (ваш друг добавил другую соль 2). так,Даже если пароль тот же,Хакеры видят нечто совершенно иное: они не смогут взломать пароль каждого, используя только один пароль.
Таким образом, «добавление соли» — это уникальная приправа к вашему паролю, которая затрудняет взлом хакерам и делает ваш пароль более безопасным.
username salt password
xw@qq.com 2dc7fcc... sha256("2dc7fcc..." + password_1)
john@163.com afadb2f... sha256("afadb2f..." + password_2)
Таким образом, «соли» — это уникальная приправа в пароле. Пароль каждого пользователя будет иметь уникальное значение соли. Даже если хакер получит базу данных, он не сможет легко взломать пароль через радужную таблицу, что сделает ваш пароль более безопасным.
Хэш SHA-256 с использованием случайной соли
import os
import hashlib
def generate_salt() -> str:
# Создайте 16-байтовое случайное значение соли
return os.urandom(16).hex()
def hash_password_with_salt(password: str, salt: str) -> str:
# использовать SHA-256 и Случайный соль Хэш пароль
salted_password = salt + password
sha_signature = hashlib.sha256(salted_password.encode()).hexdigest()
return sha_signature
# Пример
password = "abc654321"
salt = generate_salt()
hashed_password = hash_password_with_salt(password, salt)
print("Случайная соль:", salt)
print("Пароль после Хэш:", hashed_password)
Хотя SHA-256 С солью повышает безопасность паролей,Однако определенный риск взлома все же существует.。bcrypt и PBKDF2 Такие алгоритмы разработаны специально для хранения паролей, и их вычисления выполняются намного медленнее, чем обычные алгоритмы хеширования, что затрудняет взлом. Эти алгоритмы имеют встроенные случайные соли, и вычислительные затраты могут быть скорректированы по мере необходимости.
Хеширование пароля с использованием bcrypt
import bcrypt
def hash_password_bcrypt(password: str) -> str:
# Генерация соли и пароля
salt = bcrypt.gensalt() # Автоматически генерировать соль
hashed_password = bcrypt.hashpw(password.encode(), salt)
return hashed_password
def check_password_bcrypt(password: str, hashed_password: str) -> bool:
# Подтвердить пароль
return bcrypt.checkpw(password.encode(), hashed_password)
# Пример
password = "abc654321"
hashed_password = hash_password_bcrypt(password)
print("bcrypt Пароль после Хэш: ", hashed_password)
# Подтвердить пароль
is_valid = check_password_bcrypt(password, hashed_password)
print("Результат проверки пароля:", is_valid)
Именно потому, что пароли хранятся необратимо.,Когда пользователь забывает свой пароль,Система не может напрямую сообщить пользователю исходный пароль. Напротив,Система обеспечит безопасность путем сброса пароля. Отправив код подтверждения и другие методы аутентификации.,Убедитесь, что только законные пользователи могут сбрасывать пароли. Этот метод может эффективно помешать злоумышленникам получить пароли через систему.
Правильный способ хранения паролей имеет решающее значение. Независимо от того, используете ли вы алгоритмы хеширования, методы «соли» или более безопасные алгоритмы хеширования паролей, такие как bcrypt и PBKDF2),Конечная цель — защитить пользовательские данные от атак. Вместо того, чтобы разрешать пользователям сбрасывать свои пароли вместо просмотра исходного пароля,Это необходимое средство для обеспечения безопасного хранения паролей. через эту статью,Я надеюсь, что у вас есть более глубокое понимание принципов и соображений безопасности, лежащих в основе хранения паролей.