Методы хранения паролей - Хранение паролей
ОГЛАВЛЕНИЕ
Простейший подход – просто хранить
Простейший подход к управлению логинами и паролями – хранить все в виде простого текста (без шифрования и перестановки элементов) в файле или базе данных. Результат был бы таким:
Идентификатор пользователя |
Логин |
Пароль |
101 |
Bob |
Snake |
102 |
David |
Rainbow6 |
103 |
George |
DarkTower |
104 |
Eve |
Snake |
Плюсы хранения паролей в незашифрованном виде
1. Подтверждение подлинности (проверка, что пара логина и пароля совпадает с парой в таблице) очень простое – сравниваются строки!
2. Забытые пароли можно восстановить – пароль легкодоступен, если указан логин.
Минусы хранения паролей в незашифрованном виде
1. Во-первых, любой с доступом к файлу (или могущий производить выборку из таблицы) получает немедленный доступ ко всем паролям! Работник с законным доступом к файлу может распечатать файл или отправить информацию по электронной почте, и – вуаля! – все пароли скомпрометированы.
Но SQL 2005 поддерживает шифрование – его недостаточно? Нет, шифрования SQL недостаточно. Встроенное шифрование защищает только информацию на диске. Если пользователю разрешено обращаться к данным (выполнять SELECT), SQL автоматически расшифрует информацию. Если веб-приложению разрешено обращаться к данным (как иначе сравнить логин и пароль?), то хакер, взламывающий приложение, может обратиться к данным, получив тот же доступ, что и веб-приложение.
2. Вторая проблема заключается в том, что во время обмена аутентификационной информацией пароль видим в сети. Если везде не используется защищенная связь, пароль будет виден при прохождении по сети. Например, даже если веб-приложение использует SSL (уровень защищённых сокетов) для отправки пароля, пароль по-прежнему виден, когда сервер веб-приложения выбирает информацию из удаленной базы данных. Результаты запроса передаются по сети незашифрованными.
Допустимо ли хранить пароли в незашифрованном виде?
• Если хранилище данных зашифровано (например, используется SQL Server 2005),
• и внутренняя сеть связи сильно защищена (используется только IP-SEC или туннель VPN (виртуальная частная сеть) для связи между серверами),
• и используется только защищенная связь между клиентом приложения и сервером приложения,
• и вы уверены, что все работники с доступом к базе данных вообще не совершают ошибок (таких как печать парольной информации или сохранение в файл),
• и вы уверены, что никто другой не имеет физического доступа к любому из используемых серверов.
Тогда да, хранить пароли в незашифрованном виде нормально.
Шифрование паролей – чуть безопасней
Лучший подход к хранению паролей (и единственная обоснованная альтернатива, если пользователям надо иметь возможность восстанавливать пароли) – шифрование паролей перед их сохранением.
Данный подход основан на обладании тайной. Тайной является алгоритм шифрования или ключ, используемый вместе с современным алгоритмом шифрования.
Шифрование паролей – обратимая операция. Тайна используется для искажения пароля, и та же самая тайна может быть использована для восстановления оригинального пароля. Когда пользователь задает пароль, сохраненный пароль расшифровывается с помощью тайны, и пароли сравниваются. Альтернативный подход – зашифровать предоставленный пароль с помощью тайны и сравнить две искаженные версии – совпадение показывает, что предоставлен правильный пароль.
Если пользователю надо восстановить пароль, сохраненный пароль расшифровывается и доставляется пользователю (обычно по электронной почте).
Идентификатор пользователя |
Логин |
Пароль |
101 |
Bob |
k468dD8F |
102 |
David |
56lkV#p6 |
103 |
George |
8Fk4lVQ0 |
104 |
Eve |
k468dD8F |
Плюсы шифрования с помощью тайны
1. Забытый или утерянный пароль можно восстановить.
2. Только одну тайну (алгоритм или ключ) надо хранить безопасно.
3. Для многопользовательских распределенных приложений при использовании шифрования надо передавать незашифрованный пароль (для проверки) или надо передавать тайну для выполнения аутентификации в клиенте.
Минусы шифрования паролей
1. Если тайна скомпрометирована, все пароли скомпрометированы. Если у кого-то есть доступ к тайне и к хранилищу паролей, все пароли могут быть расшифрованы!
2. Только доступа к хранилищу паролей достаточно, чтобы предоставить информацию о паролях, так как все пароли шифруются с помощью одинакового алгоритма. Если два пользователя имеют одинаковый зашифрованный пароль, они также должны иметь одинаковый пароль. Хитрые хакеры с доступом к хранилищу паролей могут создать пользователей с известными паролями и проверить на наличие других пользователей с таким же паролем. Такой тип атаки является разновидностью атаки с известным открытым текстом. Такие атаки можно остановить с помощью соли (смотри ниже).
3. При использовании блочного шифра длина пароля должна храниться в составе зашифрованного пароля. Надо хранить длину, потому что блочные шифры всегда дают блок зашифрованного текста фиксированного размера. Если длина пароля не зашифрована (например, если хранится как столбец в таблице), информация очень полезна для взломщиков паролей. Знание точной длины пароля сильно упрощает угадывание пароля.
Приемлемо ли такое решение хранения паролей?
Если восстановление утерянного пароля обязательно, то да – это единственное приемлемое решение. Несколько рекомендаций:
• Храните тайну в защищенном месте. Жесткое задание тайны в коде приложения – плохое решение. Хранение тайны в файле (даже в файле web.config) – ужасная идея. Если надо использовать тайну, храните ее в базе данных (ограничение доступа путем требования аутентифицированного подключения) или в ключе реестра с ограниченным доступом.
• Используйте надежный алгоритм шифрования (примеры ниже), не создавайте свой собственный и не используйте тривиальный алгоритм шифрования. Если вы не знаете, что именно делаете, ваш собственный алгоритм может быть очень легко взломать.
• Используйте соль (смотри ниже), чтобы не дать двум пользователям с одинаковым паролем иметь одинаковый зашифрованный пароль.
• Выходные данные шифрования двоичные и должны быть закодированы, если хранятся как текст. Если хранение двоичных данных приемлемо, кодирование не требуется, но если зашифрованные пароли должны храниться как текст, обдумайте использование RADIX64 для преобразования двоичных данных в текст. RADIX64 использует символ для каждых 6 битов, увеличивая выходные данные на 33%.
Хранение хешированных паролей – необратимое решение
Криптографическая хеш-функция является необратимой функцией. Хеш-функция принимает входные данные любой длины и генерирует уникальные выходные данные постоянной длины. Например, если пароль (любой длины) хешируется криптографической хеш-функцией MD5, результатом будет 128 битное число, однозначно соответствующее паролю. Криптографические хеши работают не только на паролях – если криптографический хеш двух файлов идентичен, то два файла идентичны.
В последние годы в связи с ростом вычислительных мощностей некоторые криптографические хеш-функции больше не рекомендуется использовать (MD4, MD5, SHA1). Однако их допустимо применять для хеширования паролей. Или же измените код так, чтобы он использовал SHA2.
При хранении хешированных паролей пароль хешируется (прогоняется через алгоритм хеширования), и полученный хеш хранится вместо пароля. Чтобы сравнить пароли, захешируйте указанный пароль с помощью той же самой хеш-функции и сравните результаты. Если хеши совпадают, пароли совпадают.
Прелесть необратимой функции заключается в том, что невозможно вычислить пароль на основе хеша. Хешированные пароли неустойчивы к атаке перебором – при наличии словаря и хеша пароля хакер может вычислить хеши всех слов в словаре, сравнить слова с хешем пароля и узнать пароль. Надежные пароли (содержащие буквы, цифры и специальные символы) помогают защититься от атак перебором.
Плюсы хранения хешированных паролей
1. Оригинальный незашифрованный пароль вообще не хранится. Даже если хранилище пароля скомпрометировано, только хеши становятся общедоступными.
2. Длина пароля не хранится и не поддается оценке, что сильно затрудняет взлом пароля.
3. Не нужна тайна, так как никакая тайна не используется для хеширования пароля.
4. Для многопользовательских распределенных приложений хеш пароля может использоваться для аутентификации. При использовании шифрования приходится передавать незашифрованный пароль (для проверки) или приходится передавать тайну для выполнения аутентификации в клиенте.
Минусы хранения хешированных паролей
1. Утерянные пароли нельзя восстановить (кроме как использовать методы перебора). Новый пароль приходится создавать и передавать пользователю.
2. Как и для зашифрованных паролей, если не используется соль (смотри ниже), пользователи с одинаковым паролем будут иметь одинаковый хеш пароля.
Приемлемо ли такое решение хранения паролей?
Да, но следуйте следующим рекомендациям:
• Используйте надежную криптографическую хеш-функцию. MD5 и SHA1 не рекомендуются. SHA2 – текущий фаворит. Если нужно использовать MD5 или SHA1, используйте более стойкий алгоритм соления.
• Используйте соль (смотри ниже), чтобы не дать двум пользователям с одинаковым паролем иметь одинаковый зашифрованный пароль.
• Выходные данные хеширования двоичные и должны быть закодированы, если хранятся как текст. Если хранение двоичных данных приемлемо, кодирование не требуется, но если хешированные пароли должны храниться как текст, обдумайте использование RADIX64 для преобразования двоичных данных в текст. RADIX64 использует символ для каждых 6 битов, увеличивая выходные данные на 33%.