О паролях и парольных фразах
В бложике описал известную проблему консольного клиента mariadb, который не может сожрать пароль, длинее 80 символов: https://lor.sh/@umnik/111828511992647563
Это привело к небольшому, но полезному спору. На одной стороне я, с фразой в более 90 символов, на другой стороне уважаемый (не ирония, не шутка) в своих кругах человек, считающий, что это бессмысленно. Кстати, рекомендую подписаться на канал этого человека, если вы связаны с ИБ, он правда хорош (нет, не реклама :); да и какая реклама, если у него почти 8k человек): https://t.me/infosecmemes
Предполагаю, что оппонент отталкивается от, в общем-то, правильного утверждения, что 18+ символов — это великолепный пароль, который уже не перебрать за разумное время.
О парольных фразах
Однако у меня не пароль, а парольная фраза (пассфраза). В чём разница:
- все слова, составляющие фразу – словарные. И хотя руками я их почти не ввожу, но если придётся — не будет с этим проблем. Читаешь следующее слово, скажем
синий
и просто пишешь, не ломая пальцы, вводя всякие!"№;%:?*¡½^@#$¿⅛′˝
типичных паролей. Более того, читать можно много слов за раз:синий верблюд летит на запад
. А ещё нет проблем использовать пассфразы в скриптах, т.к. не приходится переживать за экранирования - для пассфраз запоминаемость не является плохим свойством! Вместе с ассоциативностью связи с целевым ресурсом, это позволит вспомнить пассфразу без привлечения менеджеров паролей. Скажем, есть у вас контейнер
VeraCrypt
. Создали ассоциацию сВера
и сразу извлекаете из своей памяти пароль:Вера, Надежда, Любовь и мать их София. Жили в Риме. День памяти - 30 сентября
.
В общем-то всё такое же можно применить и к паролям, но:
- паролям характерно требовать использование разных регистров букв, чисел, иногда специальных символов. В пассфразах же главное — это БОЛЬШАЯ (с точки зрения паролей) длина, а не сложность. Пассфраза в 18 символов – это очень плохая пассфраза, никуда не годится
- паролям характеро быть плохо запоминаемыми. Если пароль вводится каждый день и несколько раз в день – запомните без проблем. Но забудете, когда перестанете использовать. Личный пример: когда-то я работал в компании с доменными политиками и вводил доменный пароль много раз в день. Конечно я помнил свой последний пароль ещё несколько недель после увольнения. Но сейчас не могу вспомнить даже в совсем общих чертах, даже примерно. Не смогу даже сказать, был ли там восклицательный знак или цифра
3
О рекомендациях NIST
Предлагаю просто обратиться к рекомендациям NIST
. Опираться буду на ещё черновую версию NIST SP 800-63 Digital Identity Guidelines
. Если кому-то надо текущую, а не черновую, то -4
в ссылке замените на -3
. Но всё равно эта черновая всё же станет стандартом, а ссылка не изменится.
Нам нужен NIST Special Publication 800-63B
Запоминаемый секрет — это то, что мы привыкли называть паролями или, если речь о цифрах, – пинами. Это всё то, что вы знаете (или способны заучить, будучи обычным человеком). Секретам нужно быть достаточно сложными, чтобы их было сложно распознать. См. раздел 5.1.
- минимальная длина должна быть не менее 8 символов
- секреты длиной от 64 символов обязаны приниматься и корректно обрабатываться
- ограничения сверху NIST не накладывает, но наоборот, говорит, что должно принимать от пользователя столько, сколько пользователю удобно
- должны приниматься все печатные символы ASCII, пробелы, а также символы юникода
- допустимо (то есть не запрещено, но и не обязательно) отбрасывать вайтспейсы в начале и в конце ввода, как защиту от возможных опечаток. Но тогда и проверка на длину должна быть после отбрасывания
- допустимо проверять пароль в обоих регистрах для первого символа, как ещё один способ исправления опечаток. Обращаю внимание – проверять оба регистра, а не безусловно приводить первый символ к какому-то регистру
- проверять нужно каждый символ секрета, отсечка по длине недопустима
- ЗАПРЕЩЕНО требовать секреты в смешанных регистрах
- ЗАПРЕЩЕНО требовать специальные символы
- ЗАПРЕЩЕНО требовать периодической смены секретов
- но если была утечка или выявлена компроментация – необходимо требовать смену секрета
Здесь жесть для тех, кто хочет шевеления волос на жопе
- символы юникода считаются по code point, а не по code unit и не по графемам или ещё как-то
- что только усложняет лично мне понимание. Я бы хотел считать по графемам. Потому что
🐻❄️
— это один, два, три или четыре code points? Ведь ваш любимый ЯП и RFC по юникоду могут вкладывать разные смыслы в термин. В общем, я бы считал полярного медведя одним символом, потому что это тоже просто такая вот буква такого вот алфавита. Но чтобы было ещё хуже, вот: - символы юникода должны быть нормализованы по формам KD (совместимая декомпозиция, NFKD) или KC (совместимая композиция, NFKD). См. рис. 6: https://www.unicode.org/reports/tr15/
- в NFKD символы упрощаются до похожих, но привычных. Скажем ¼ приводится к
1
,/
и4
, а™
кt
иm
- в NFKC, в дополнение к NFKD, ещё выполняется композиция, то есть обратная операция. Сначала декомпозируем для упрощения, а потом снова композируем для сведения. В вики в примере символ
が
сначала сталか
и゙
, а потом сноваが
. И если вам кажется, что NFKC просто ничего не делает в конечном итоге, то нет. Потому чтоẛ̣
NFKD разложил наs
,̣
и `̇
, а NFKC собрал вṩ
, см. всё тот же https://www.unicode.org/reports/tr15/
- в NFKD символы упрощаются до похожих, но привычных. Скажем ¼ приводится к
- что только усложняет лично мне понимание. Я бы хотел считать по графемам. Потому что
при этом вы, как разработчик ПО, где вот эти все чудеса происходят, обязаны предупредить пользователя, что вводимые им символы могут быть представлены иным способом, что может повлиять на успешность аутентификации
запрещено сохранять подсказки о пароле, доступные без должной проверки
- на мой взгляд, требование NIST не запрещает прямо показывать подсказки, но запрещает показывать их, если уж совсем никак пользователь себя не показал. Например, пользователь уже залогинен, пытается изменять настройки и вы запрашиваете пароль ещё раз для проверки. Сейчас показать подсказку можно. Но если он не был залогинен и пытается войти – подсказку нельзя показывать
запрещено вовсе в качестве подсказок запрашивать данные, которые можно узнать, типа клички первого домашнего животного
задаваемые пароли необходимо проверять по базе предсказуемых и переиспользуемых, но дополнительно МОЖНО (но не является обязательным) делать некоторые другие проверки, типа:
- есть в утечках
- словарные слова
- повторяемые символы и очевидные последовательности (
aaaa
,qwerty
) - слова, специфичные для окружения. например, название самого сервиса (mail.ru), логин и производные от логина
если пароль в чёрном списке, нужно прямо сказать об этом пользователю. Просто так посылать его нельзя
запрещается использовать чрезмерно большие чёрные списки. Что бы под этим не подразумевал NIST
сервис обязан иметь механизмы защиты от перебора (ограничение на попытки)
- само ограничение NIST ставит большим для нормального пользователя и маленьким для реального перебора: не более 100 попыток
разрешены механизмы детекта ботов, троттлинг запросов, ограничение по IP, метаданным и т.п.
- когда пользователь успешно вошёл, все “накопленные” счётчики недоверий должны быть сброшены для этого IP адреса
необходимо позволять использовать менеджеры паролей. Важно здесь то, что НЕОБХОДИМО РАЗРЕШАТЬ фичу вставки текста
необходимо разрешать показ секрета за звёздочками
- разрешать нужно не только пока кнопка мыши/палец держат кнопку, а именно переключение состояний
- запрещено сбрасывать состояние “видимо”, пока идёт ввод
для мобильных устройств разрешено (не требуется, не запрещено) кратковременно показывать вводимый символ и затем скрывать его за звёздочкой
Для запоминаемых секретов NIST не выдвигает никаких требований к энтропии самих секретов, перекладывая отвественность на бэкэнд при их хранении (и к алгоритмам шифрования ещё)
Почему так?
Некоторые требования NIST выглядят странными. Ну как так – пароль без требования к разным регистрам букв, без требования чисел и спецсимволов? Но NIST отталкивается от человеческой природы. Ну вот лень нам порою делать правильно. NIST предлагает не по башке бить за это, а принять природу и поменять подход на такой, что даже если человек ленив, он всё равно сделает нормально.
Ведь нет никакого запрета принимать специальные символы. Более того, их обязательно нужно уметь принимать.
С другой стороны мы понимаем, что если не просить разнообразия символов, получим совсем говно. Однако:
- совсем говно должно отсекаться чёрными списками + правилами запрета повторений и последовательностей
- длина паролей ограничивается снизу. Нет никаких запретов требовать от 16 символов, например. Главное, что не менее 8 и нет ограничений сверху
Такие мягкие рамки подведут пользователя к как раз парольным фразам и менеджерам паролей. Второе опустим, а вот профиты первого:
- простота запоминания приведёт к тому, что пользователь не будет писать фразу на бумажке и класть под клавиатуру
- он не будет перепробовать десять вариантов, как же он задавал, вторая заглавная или третья, или ещё как-то
- пользователю будет не сложно запоминать даже достаточно длинные фразы
- пользователю не нужно разбираться, 0 это или О. I это или l
- их проще копировать. Выделение простых слов не вызывает проблем
- их можно легко передать голосом другому человеку
- сколько угодно можно говорить, что диктовать пароль никогда не пригодится, но это до первой необходимости объяснить что-то своей матери
Пример выше с Верой – это более 70 символов, но слушатель радио “Вера” уже запомнил его.
Есть у парольных фраз ещё одно очень важное преимущество – их легко писать на “проблемных” устройствах. Например, попытаться залогиниться в веб сервисе на телевизоре или какой-нибудь PlayStation без подключения клавиатур и подобного. Потому что и в современных телевизорах, и в приставках, есть подсказки слов их остаётся только выбирать из предлагаемых.
NIST прямо указывает, что нужно принимать 64+ символа и это нужно для фраз: https://pages.nist.gov/800-63-4/sp800-63b.html#memorizedsecrets При том что для русского языка это всего в среднем 9 слов и 8 пробелов между ними (при средней длине слова в 6 букв).
Но парольные фразы не идеальны, есть у них и проблемы, часть из которых худо-бедно можно приуменьшить:
- они, блин, длинные
- не считая менеджеров паролей, тут немного помогают клавиатуры смарт-устройств, которые без проблем позволяют добить слова. При чём это дёшево и работало даже на древних тупофонах и называлось T9 (земля ему пуховик)
- эти же самые клавиатуры умных устройств могут заучивать последовательности слов (такое бывает, если софт писан жопой и автор не соблюдает правил ОС, под которую пишет)
- достаточно большое количество слов (9+ для русского языка при 64+ символах) во фразе помогает снизить или вовсе убрать урон
- от говнософта не спасут и пароли. Было время, когда Samsung устройства на Android охотно подсказывали пароли, потому что заучивали всё, что пишут с них, включая поля паролей. И понять, что это пароль всё же сильно проще, чем понять, что это одно из слов парольной фразы (кстати, это слово может быть и из серидины фразы)
- парольные фразы тоже бывают очевидными и предсказуемыми
- NIST нигде не говорит, что стоп списки паролей не должны применяться и к фразам
- здесь, кстати, меньше 64 символов
Фразы лучше паролей?
Нет. Пароли – это почти также круто, как Чечня. Но людям тяжело делать хорошие пароли и соблюдать в целом правила и эти люди стали ипользовать дыры парольных политик для облегчения жизни себе и, как итог, злоумышленникам. Фразы стали лишь ответом на использование этих дыр.
То есть если лично ты делаешь всё по красоте – 18 символов пароля с самыми извращёнными символами из юникода и вообще не знаешь этот пароль, а хранишь его в православном KeePass, на который ещё и минимум 2 фактора навешано; если ещё и на сами сервисы вешаешь вторые факторы, то нет никакой нужны использовать фразы.
А я перешёл на фразы (когда это возможно) из-за ерунды – не смог однажды в скрипт передать пароль. То есть в итоге сделал, но пришлось внимательно расставлять экранирования. Это, кстати, было ещё во времена Windows и это было в batch. Если вам приходилось писать скрипты на batch, то вы поняли глубину моей душевной травмы.
Но зачем настолько длинные, зачем 91 символ (с чего всё и началось)? Да не за чем. Просто стояло число 11 в генераторе и он сделал 11 слов. Вот и получилась такая длина – просто совпадение. Было бы 10, то я бы мог и не попасть на изначальную проблему mariadb клиента. Таким образом вся статья родилась из-за того, что просто стояло число 11 и я его не менял. Мне ведь всё равно, 90 там символов или 200. А с точки зрения NIST важно, что их больше 64