Passgen: Генератор паролей, использующий регексоподобный синтаксис для создания надежных паролей любой формы.

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

В идеале пароли должны быть как можно длиннее.1. Если раньше рекомендовалось использовать политики паролей (например, принудительное использование специальных символов), то в настоящее время лучше избегать этого.2и вместо этого поощрять длинные пароли. В популярном компьютерном комиксе XKCD #936 отмечается, что длинные пароли на основе слов обладают большей надежностью и запоминаемостью, чем пароли на основе специальных символов:

Исходя из этого, я решил создать инструмент, который мог бы помочь в генерации случайных, надежных паролей различной формы. Я хотел, чтобы он был очень гибким, чтобы вы могли легко создавать пароли различной формы (например, 16 буквенно-цифровых символов или 4 английских слова).

Регулярные выражения

Я также очень люблю использовать регулярные выражения. Это язык, который часто используется для фильтрации или поиска текстового содержимого. Например, регулярное выражение [a-z]{8} будет соответствовать любому вводу, состоящему ровно из восьми строчных латинских символов. Если вы не знакомы с регулярными выражениями, вот таблица, демонстрирующая их синтаксис:

Описание Regex
Буквальная строка abc abc
Либо a, либо b, либо c [abc]
Любой строчный латинский символ [a-z]
16 строчных латинских символов [a-z]{16}

Обычно регулярные выражения используются в коде для проверки вводимых данных. Например, вы можете использовать регулярное выражение [a-z0-9.]{3,16}@yourcompany.com, чтобы проверить, является ли что-то действительным адресом электронной почты компании.

Что, если бы я мог создать инструмент, которому можно дать регулярное выражение, и он будет оценивать его в обратном порядке, выдавая строку, которая соответствует ему, а не определяя, соответствует ли заданная строка?

Из этой идеи родился passgen. Он начинался как небольшой однофайловый проект на языке Си, а развился в нечто, что я считаю действительно полезным. Он поддерживает небольшое подмножество синтаксиса регулярных выражений и выдает случайную строку, соответствующую им. Например:

# generate a password with eight lower-case latin characters
$ passgen "[a-z]{8}"
nsaaemni
# generate a password with twelve alphanumeric latin characters
$ passgen "[a-zA-Z0-9]{12}"
Lp7FBOldLhJC
Войти в полноэкранный режим Выйти из полноэкранного режима

Passgen полностью поддерживает юникод, что означает, что вы можете генерировать пароли и для других языков. Вот несколько примеров этого в действии:

# password with german characters
$ passgen "[a-zßäüöA-ZÄÜÖ0-9]{8}"
6Mu6cüYI
# password with sixteen japanese characters
$ passgen "[u{3040}-u{309F}]{16}"
しがぢゐめまゔょぎっきす゚だぃぷ
Вход в полноэкранный режим Выход из полноэкранного режима

Списки слов

Одной из причин, по которой я создал Passgen, было желание создавать более запоминающиеся пароли для себя. Использование совершенно случайных букв делает пароли короткими, но не запоминающимися, как отмечалось ранее в XKCD. Поэтому у passgen есть возможность читать списки слов и выбирать из них случайные слова.

Пример Шаблон
Случайное слово из списка слов w{english}
Шесть случайных слов из списка слов, разделенных дефисом (w{english}-){5}w{english}
Шесть случайных слов из списка слов, разделенных дефисом, за которым следует случайное число (w{english}-){5}w{english}[0-9]{1,2}

Например, если вы работаете на Debian или Ubuntu, и у вас установлен пакет wamerican, то список слов будет доступен по адресу /usr/share/dict/american-english. Если вы работаете на другой платформе, скорее всего, вы можете воспользоваться аналогичными предустановленными списками слов. Использование флага командной строки --wordlist позволит вам загрузить этот список слов и затем ссылаться на него в шаблоне.

# pick 6 random words
$ passgen --wordlist english:/usr/share/dict/words "(w{english}-){5}w{english}"
vichyssoise-outstretching-requisite-weekended-homogenizes-calypsos
# pick 6 random words, and a one or two digit number
$ passgen --wordlist english:/usr/share/dict/words "(w{english}-){5}w{english}[0-9]{1,2}"
Karamazov-tasselling-pianos-shirr-devoutly-bullrings0
Войти в полноэкранный режим Выход из полноэкранного режима

Цепочка Маркова

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

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

Чтобы использовать эту функцию, используйте m{wordlist}, а не w{wordlist} в шаблоне, все очень просто!

# generate five words from english markov chain
$ passgen --wordlist english:/usr/share/dict/words "(m{english}-){4}m{english}"
dam-bloodling-tempouthed-distnuminest-muchee
# generate four words from english markov chain and a number
$ passgen --wordlist english:/usr/share/dict/words "(m{english}-){3}m{english}[0-9]{1,2}"
lariticitude's-lieu's-gadorayons-flers44
Вход в полноэкранный режим Выход из полноэкранного режима

Сложность

Каждый раз, когда passgen предлагает выбор между несколькими вариантами, он знает, сколько вариантов существует, и таким образом может отслеживать, насколько «случайным» является ваш пароль. Это означает, что он может сказать вам, сколько битов случайности содержит ваш пароль, что может рассказать вам о том, насколько сложно злоумышленнику взломать ваш пароль, если он знает шаблон, который вы использовали для его генерации. Например, если ваш пароль имеет 80 бит энтропии, то для его взлома потребуется в среднем 280=12089258196146291747061762^{80}=1208925819614629174706176

280=1208925819614629174706176 попыток отгадать.

Используйте флаг --complexity, чтобы указать passgen выводить свою оценку сложности. Вот несколько примеров:

# eight lowercase alphabetic characters
$ passgen --complexity "[a-z]{8}"
entropy: 37.603518 bits
qhziaohr
# twelve alphanumeric characters
$ passgen --complexity "[a-zA-Z0-9]{12}"
entropy: 71.450356 bits
IoSNTUNU3M1Q
# six random dictionary words
$ passgen --complexity --wordlist english:/usr/share/dict/words "(w{english}-){5}w{english}"
entropy: 100.025099 bits
smirked-Ila-ounces-circumstance's-bedpan-process
# six random markov chain words
$ passgen --complexity --wordlist english:/usr/share/dict/words "(m{english}-){5}m{english}"
entropy: 125.801760 bits
confabriquing-mas-Onei-scrite-elaw-inast
Войти в полноэкранный режим Выйти из полноэкранного режима

Важно помнить, что эта функция не совершенна. Если вы дадите passgen шаблон типа (a|a){5}, который технически имеет ноль бит энтропии (он всегда выдает aaa), passgen все равно вычислит ненулевую сложность, потому что passgen делает выбор (между первым a и вторым a).

Случайность

Passgen будет предпочтительно использовать безопасный генератор случайных чисел ядра в качестве источника случайности, это getrandom() в Linux и arc4random_buf() в macOS. Он возвращается к использованию /dev/urandom. Однако источник случайных данных настраивается, он также может использовать посевной генератор псевдослучайных чисел, но в настоящее время для этого реализован только небезопасный алгоритм xorshift.

Мелочи

Passgen использует libseccomp3 на платформах amd64 для «песочницы», ограничивающей его только небольшим количеством разрешенных системных вызовов.

Он также может выводить данные в виде JSON, передав опцию --json.

Попробуйте

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

Если вы работаете на Debian или Ubuntu, релизы .deb будут вам полезны, потому что они позволят вам легко установить (и удалить) passgen с APT.

Резюме

На сайте есть обзор синтаксиса, который можно использовать, но вот краткое резюме.

Пример Паттерн
Сгенерировать литеральную строку abc. passgen "abc"
Выберите символ из a, b, c passgen "[abc]"
Выберите символ из диапазона a-z. passgen "[a-z]"
Повторите a четыре раза passgen "a{4}"
Выберите четыре символа нижнего регистра passgen "[a-z]{4}"

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

  • Дословные символы. Шаблон abc генерирует «пароль» abc. Они просто передаются.
  • Наборы символов, заключенные в скобки. Вы можете либо перечислить все разрешенные символы, либо использовать диапазоны символов, которые являются инклюзивными. Примеры: [abc], [a-zA-Z0-9], [0123456789abcdef].
  • Группы, заключенные в паретес. Группы позволяют перечислить один или несколько возможных шаблонов. Примеры: (word) генерирует слово, (this|that) генерирует this или that, ([a-z]|[0-9]) генерирует строчный латинский символ ([a-z]) или число ([0-9]).
  • Повторять. Использование скобок позволяет повторить то, что было раньше. Вы можете указать либо фиксированное число, либо нижнюю и верхнюю границы, разделенные запятой. Примеры: [abc]{3}, [a-z]{9,12}, (this|that){2}.

Если этот синтаксис слишком сложен для вас, бинарный файл passgen также поставляется с некоторыми предустановками шаблонов, которые вы можете использовать с флагом -p. Они названы в честь программ, которые генерируют пароли, соответствующие этим шаблонам.

# generated by older versions of safari
$ passgen -p apple1
asG-mIQ-7jz-LAT
# generated by current safari
$ passgen -p apple2
lHODYM-MgdmfG-llo5kD
# generated by firefox
$ passgen -p firefox
iBpDBlTg8bX051H
Вход в полноэкранный режим Выход из полноэкранного режима

Разработка

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

  • CMake
  • компилятор языка Си (gcc или clang)
  • Git

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

git clone https://gitlab.com/xfbs/passgen
git submodule update --init
mkdir passgen/build
cd passgen/build
cmake ..
make -j8
Вход в полноэкранный режим Выход из полноэкранного режима

Если вы хотите понять, как работают отдельные части, есть также документация, созданная на основе мастер-ветки.

Тесты

В Passgen встроен ряд модульных тестов, которые можно запустить с помощью make test. Вы также можете запустить эти тесты под valgrind, если он у вас установлен, это позволит вам убедиться в отсутствии утечек памяти.

$ valgrind ./src/test/passgen-test -v
Вход в полноэкранный режим Выход из полноэкранного режима

Поддержка

Ваша поддержка высоко ценится. Если вы запустите passgen, и что-то не будет работать, пожалуйста, дайте мне знать. Вы можете написать о проблеме в репозиторий, и я постараюсь ее исправить.

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


  1. Минимальная длина паролей должна обеспечиваться приложением. Пароли короче 8 символов считаются слабыми. https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html

  2. https://www.troyhunt.com/passwords-evolved-authentication-guidance-for-the-modern-era/

  3. https://github.com/seccomp/libseccomp

  4. utf8proc, библиотека для декодирования UTF-8. https://github.com/JuliaStrings/utf8proc

Оцените статью
devanswers.ru
Добавить комментарий