Как реализовать безопасную историю паролей

23

Пароли не следует хранить в виде простого текста по очевидным причинам безопасности: вам нужно хранить хэши, а также тщательно генерировать хэши, чтобы избежать атак радужных таблиц.

Однако обычно у вас есть требование хранить последние n паролей и обеспечивать минимальную сложность и минимальное изменение между различными паролями (чтобы пользователь не мог использовать последовательность, такую ​​как Password_1, Password_2, ..., Password_ n ). Это было бы тривиально с простыми текстовыми паролями, но как вы можете сделать это, сохраняя только хэши?

Другими словами: как можно реализовать механизм безопасной истории паролей?

Wizard79
источник
2
Связанный: security.stackexchange.com/questions/4704/… (и кстати, этот сайт может быть лучшим местом для этого вопроса). Что касается «минимального изменения», я не могу представить себе какую-либо альтернативу генерации всех опций, которые можно квалифицировать как «минимальное изменение» (которое может быть МНОГО в зависимости от вашего определения!) И сравнение хэшей. Что такое определение «минимальное изменение»?
Кевин Вермеер
7
Хранение только последних n паролей означает, что пользователь выберет последовательность от 1 до n + 1 .
Йоахим Зауэр
11
Я очень скептически отношусь к тому, что такая политика паролей повышает безопасность; ИМХО, это увеличивает вероятность того, что люди прибегнут к хранению своего пароля на заметке. Ссылка Кевина - хорошая дискуссия. @KevinVermeer - вы можете измерить величину изменения как расстояние Левенштейна ( en.wikipedia.org/wiki/Levenshtein_distance ), также известное как «расстояние редактирования».
Натан Лонг
5
Если ваша безопасность такая строгая, вы можете также сгенерировать случайный пароль для пользователя, заставить его использовать его и менять его через регулярные промежутки времени. Таким образом, вы можете полностью контролировать свой пароль.
Reactgular
2
@nathan: хранение паролей на заметке на самом деле безопасно. Невозможно атаковать пароль, если у вас нет физического доступа к заметке - устранение около 99% угроз. Поместите эту записку в кошелек или кошелек, и вам, в основном, нужно будет ограбить человека, чтобы получить ее - это означает, что брешь в безопасности выявлена ​​и может быть смягчена.
Mattnz

Ответы:

22

Сохраняйте хеши и проверяйте введенный пароль на основе этих хеш-кодов, так же, как вы проверяете пароль при входе в систему. Вам потребуется сгенерировать «альтернативные» пароли из тех, которые указаны на основе числовых шаблонов, чтобы обнаружить ваши «минимальные» изменения.

При входе в систему вы проверяете введенный пароль по хешу, нет необходимости хранить пароль в текстовом виде. Та же самая хитрость работает, когда дело доходит до смены пароля, просто проверяйте введенные пароли и сгенерированные «минимальные изменения» пароли по историческим хешам. Если новый пароль подходит, переместите текущий хэш пароля в исторический набор и замените его новым хэшем для нового пароля.

Мартейн Питерс
источник
Итак, если пользователь вводит Password6, я должен определить числовую часть и попробовать, например, Password4 , Password5 , Password7 и так далее. Это верно?
Wizard79
4
@ Лоренцо: Верно. Создание альтернатив может быть настолько сложным, насколько вы хотите, просто убедитесь, что вы нашли правильный компромисс между сложностью и риском (не позволяйте вашим пользователям ждать 5 минут, пока вы проверяете все возможности с исчезающей вероятностью риска).
Мартейн Питерс
Я не уверен, что предложение заключить число в конец - это хорошее предложение для пользователей - это немного предсказуемо. И получает в геометрической прогрессии больше, если вы говорите пользователям, чтобы сделать это.
Уайетт Барнетт
2
@WyattBarnett: никто не говорит пользователям об этом. Смысл в том, чтобы обнаруживать, что пользователи делают это и не позволяют использовать «увеличенный» пароль.
Мартин Питерс
Ах, совершенно неправильно что-то здесь. Сожалею.
Уайетт Барнетт
28

Когда пользователь меняет свой пароль, попросите его ввести свой предыдущий пароль. Теперь у вас есть доступ к двум открытым текстовым паролям, даже если вы не храните простые текстовые пароли в своей базе данных.

Выполните любые проверки по этим двум паролям. Это не помешает пользователю чередовать два пароля (с суффиксом - вы можете запретить прямое чередование в соответствии с предложениями в других ответах), но предотвратит более явные случаи.

Брайан
источник
Что ж, это, безусловно, разумный обходной путь, если у вас нет необходимости проверять n предыдущих паролей, однако предложение генерировать альтернативы вовремя лучше. Но генерирование альтернатив обоих паролей еще лучше!
Wizard79
2
@Lorenzo: Идея в том, что вы проводите прямой тест против n предыдущих паролей и более сильный тест против последнего пароля. Это компромисс.
Брайан
Да. Если их текущий пароль potatoSalad1и он хочет обновить его potatoSalad2, вы говорите, что изменение слишком мало, потому что у вас есть оба простых текстовых пароля в этот момент. Но, кроме того, у вас есть только хэши, и природа хэшей заключается в том, что вы не можете определить, имели ли два хэша одинаковый или совершенно различный простой текст в качестве входных данных.
Натан Лонг
7

чтобы добавить к ответу @ martijnPieter, минимальное изменение может быть реализовано с помощью короткой грубой силы, основанной на новых и предыдущих паролях (которые вы оба имеете в наличии)

например, вы можете перебрать все пароли с расстоянием Хэмминга 1 или 2 от нового пароля и посмотреть, соответствует ли он старому проходу

но вы можете заметить, что это может снизить уверенность пользователей в том, что вы хэшируете пароли (поскольку вы, по сути, говорите, что вы можете вернуть предыдущий пароль, чтобы отклонить новый пароль)

чокнутый урод
источник
Но есть много последовательностей с большими расстояниями Хемминга, таких как февраль 2012 г. -> март 2012 г. или пт-09-28-12 -> вт-11-27-12 (даты), Password_Alpha -> Password_Beta, Pass_1111 -> Pass_2222, Pass_qwer, Pass_tyui, Pass, _op [] или Eleven -> Twelve (альтернативные системы подсчета), или FrankSmith -> FredJones -> FriarTuck или гнев -> animal -> apple (имена в каталоге компании или слова в словаре), которые злоумышленник с помощью предыдущий пароль может быть легко угадать, но ваш алгоритм будет очень трудно генерировать.
Кевин Вермеер
@KevinVermeer тогда учтет тех, кто у вас в генераторе вариаций, и признаю, что вы никогда не получите всего
трещотка урод
+1 к снижению доверия. Когда я вижу что-то, говорящее мне, что мой пароль слишком похож на тот, который я использовал три месяца назад, я сразу же задаюсь вопросом, хранят ли они их обратимо ... или у них есть отличный программист. Скептицизм обычно побеждает.
Тим Пост
5

Это действительно скорее дополнение к умному ответу @ Брайана. Снимаю шляпу перед @Martijn Pieters за добавление подробностей о том, как перебрать старые пароли на основе текущего, и у @ratchet freak за «расстояние Хэмминга». Я не удаляю свой ответ, потому что я думаю, что он обеспечивает интересную основу для их поддержки.

Современное хранилище паролей требует использования нескольких циклов надежного одностороннего криптографического хэша (SHA-512 +) с уникальной солью (128 бит +) для каждого пользователя. Но не поддавайтесь искушению хранить дополнительную информацию о каждом пароле. Чем больше информации вы будете хранить о каждом пароле, тем больше вы подрываете безопасность вашего алгоритма хеширования.

пример

Подумайте, как легко взломать пароль, если вы знаете, что:

  • Это 7 символов в длину
  • Символы 3-5 в верхнем регистре (4 ниже)
  • 1 и 7 числа
  • 6 является символом

Американская клавиатура имеет 95 печатаемых символов, поэтому, зная, что пароль длиной 7 символов, получается 95 ^ 7 = 69 833 729 610 000 = 7x10 ^ 13 перестановок. Если бы это было действительно случайно, то на взлом одного процессора 3Ghz потребовался бы год. Но:

  • Есть только 26 заглавных и 26 строчных букв
  • Есть только 10 цифр, дающих 100 возможностей для этих двух чисел
  • Всего 32 символа

Итак (исправлено благодаря @Hellion):

         26^4 (charcters 2-5 are known upper or lower-case)
        x 100 (characters 1 & 7 are digits)
        x  32 (character 6 is a symbol)
         ====
1,462,323,200 possible passwords.

Это в 50000 раз легче взломать! Хранение полезной информации для предотвращения подобных паролей в этом случае заняло у вас время взлома 7-символьного пароля с года до пары часов. Расшифровка всех ваших паролей на мощном многопроцессорном рабочем столе с хорошей видеокартой и небольшим терпением теперь вполне осуществима. Я надеюсь, что этот простой пример демонстрирует, что чем более содержательно вы сможете сравнить похожие пароли, тем менее безопасным будет ваше хеширование.

Важность сильного хеширования

Базы данных с паролями регулярно крадут, с огромными взломами в новостях каждый месяц. Черт, только в прошлом месяце штат SC потерял все номера социального страхования - упс! Сколько еще этих нарушений скрыто?

Заключительная мысль

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

ГленПетерсон
источник
1
второстепенная гнида: возможности пароля все еще мультипликативны, так что это (26 ^ 4) * 100 * 32 = 1 462 323 200. Если мы предположим, что взлом (95 ^ 7) возможностей занимает год, то взлом этого меньшего количества возможностей займет около 11 минут.
Геллион
@ Хеллион - Ой! Спасибо что подметил это. Я исправил это.
ГленПетерсон
1

Во-первых, вы можете сохранить хэши для последних «n» предыдущих паролей, чтобы вы могли проверить, дублирует ли их новый пароль предыдущий пароль. У вас также есть простой текст их текущего пароля (потому что они вошли в систему или предоставили его вам для аутентификации своего запроса на изменение пароля), и их новый пароль, чтобы вы могли проверить минимальные изменения между этими двумя паролями.

Если (для вас) очень важно напрямую сравнить эти два пароля с «n» предыдущими паролями, то вы должны хранить эти пароли (зашифрованные), чтобы иметь возможность восстановить их позже.

Хотя это можно рассматривать как недостаток безопасности, для обеспечения достаточной безопасности могут быть реализованы методы шифрования.

  1. Сохраните каждый пароль (зашифрованный) для последних «n» паролей.
  2. Сохраните дату и время, когда был создан самый последний пароль.
  3. Сохраните хэш самого последнего пароля.
  4. Зашифруйте все пароли, используя хэш (соленый) текущего пароля, а также временную метку создания пароля и, возможно, что-то вроде номера учетной записи или адреса электронной почты.
  5. Отключайте шифрование и повторно шифруйте все пароли каждый раз, когда создается новый пароль.

Затем, в любое время, когда вы меняете пароль, вы можете дешифровать все старые пароли и выполнить все свои тесты с минимальными изменениями.

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

Кроме того, для старых паролей их не обязательно хранить в виде простого текста. Они могут храниться каким-то запутанным способом. Или хранится в виде алфавитного списка символов в пароле.

Я не говорю, что это рекомендуется делать в общем случае, но если в вашем случае требуется описанная вами задача, то это один из способов выполнить ее с некоторыми мерами безопасности.

Кевин Феган
источник
Этот ответ делает несколько ужасных предложений с точки зрения безопасности. Мы не должны иметь возможность легко расшифровывать пароли и хранить их «каким-то образом запутанным образом» вместо того, чтобы их сильно шифровать.
user45623