Генерация xkcd паролей на PHP

    Известный комикс xkcd подсказывает нам, что пароль, который состоит из 4 часто употребляемых слов — легко запомнить и сложно подобрать.


    Перевод, оригинал

    Все текущие реализации этого метода генерации паролей рассчитаны на английские слова, а значит пароли сложнее запомнить русскоязычным. Я вооружился частотным словарем русского языка, и сделал PHP библиотеку, которая поддерживает генерацию паролей из нескольких наборов слов:
    • английские слова (например, «idea critic happy chinese»);
    • русские слова (например, «порошок земля нуль платье»);
    • транслитерированные русские слова (например, «vysota razum bumazhka razmer»).

    Код и списки слов на GitHub.


    Установка с помощью composer


    {
        "require": {
            "barzo/password-generator": "dev-master"
        }
    }
    

    Генерация паролей


    Пароли генерирует статическая функция Generator::generate, которая принимает три параметра: список слов, длину пароля (количество слов) и разделитель слов. Например, генерации пароля из 5 транслитерированных слов разделенных дефисом:

    $wordList = new Barzo\Password\WordList\RuTranslit();
    
    echo Generator::generate($wordList, 5, '-');
    

    Вывод будет содержать строку похожую на:

     dovod-gore-sever-nomer-druzhka
    

    Для каждого списка слов есть синоним для быстрого вызова:

    echo Barzo\Password\Generator::generateEn();
    echo Barzo\Password\Generator::generateRuTranslit();
    echo Barzo\Password\Generator::generateRu();
    


    Списки слов


    Английские слова (WordList\En)

    Список из 2048 наиболее часто используемых слов английского языка на основании корпуса современного американского английского.

    Пример вывода — idea critic happy chinese.

    Русские слова (WordList\Ru)

    Список из 2048 наиболее часто используемых русских имен существительных на основании национального корпуса русского языка.

    Пример вывода — порошок земля нуль платье.

    Русский транслит (WordList\RuTranslit)

    Список из 2048 слов на основании предыдущего списка, из которого исключены слова, которые содержат неоднозначные для транслитерации буквы (ц, щ, ь, ъ).

    Пример вывода — vysota razum bumazhka razmer.

    Демо


    Попробовать библиотеку можно тут.

    Реализация с этими списками слов на JS (исходники, автор — perevedko).
    Метки:
    Поделиться публикацией
    Реклама помогает поддерживать и развивать наши сервисы

    Подробнее
    Реклама
    Комментарии 52
    • +6
      Вот только большинство сервисов требуют (да как можно вообще требовать!) заглавные буквы, цифры и даже иногда знаки.
      • +1
        А что если заменять пробел на цифру, а некоторые слова писать с заглавной? Сложность запоминания увеличится не так сильно, я думаю.
        • 0
          Можно по схеме, например, пробелы нумеровать (1, 2, 3, ...), а первую, вторую или последнюю букву — заглавную… Или еще круче, в первом слове — первую, во втором — вторую, в третьем — третью…

          Только это все все равно не решит проблему.
          • 0
            И почему же не решит? Конечно, если так выдумывать, то нет, однако paper0winter0snow0music например запомнить не так сложно.
            • 0
              ну одну комбинацию — да. А если сайтов с паролями 1000? везде один пароль использовать?
              • 0
                С этим согласен, да. Тут уже, как никак, придется придумывать что-то сложнее.
      • +2
        По поводу реализации ничего сказать не могу, лишь по поводу метода.
        Брюс Шнайер (и многие другие секьюрити специалисты) не рекомендует так делать: www.schneier.com/blog/archives/2014/03/choosing_secure_1.html
        • +3
          Есть два варианта реализации: пользователь сам определяет, какими будут 4 слова, или за пользователя делает это генератор псевдослучайных чисел. Шнайер пишет о ненадёжности метода, имея в виду первый случай — здесь действительно подбор возможен, так как слова не случайны. Во втором случае всё честно: даже имея в своём распоряжении словарь, который использовала жертва и зная о том, как формируется пароль, атакующий будет вынужден перебрать N4 комбинаций слов, где N — число слов в словаре. Для словаря из 2000 слов это 16 триллионов комбинаций.

          Однако надёжность такого способа зависит не только от числа слов в словаре, но и от используемого способа хэширования пароля — устойчивость имеется, только если невозможен быстрый перебор. При 1000 комбинаций в секунду это перебрать нереально. Но если используется какой-нибудь MD5 — переберётся за несколько минут даже в домашних условиях на хорошем GPU, не говоря уже о кластерах, где таких GPU могут быть десятки.
          • 0
            > При 1000 комбинаций в секунду это перебрать нереально.

            Не очень понятно, как вообще перебирать 1000 комбинаций в секунду? Конечно, если у нас есть база хэшей и известен алгоритм их формирования, мы можем подбирать так пароли. Но если мы просто долбимся к сайту, что мешает сайту при каждой попытке ввода неверного пароля увеличивать время ожидания следующей попытки ввода в 2 раза? 5 секунд, 10 секунд, 20 секунд и так далее — 1000 попыток будут просто недостижимы.
            • 0
              Речь идет уже об имеющейся БД сайта с хэшами паролей.
        • +1
          Я вот не сильно разбираюсь в подобном, но допустим:
          — в рунете используют кириллицу, латиницу, целые числа и пару символов для пароля
          — подбор пароля тоже работает по тому же списку?

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

          Так допустим для себя я сохраняю один китайский иероглиф (пусть будет 異) на ПК и телефоне и везде его использую. Конечно там где нет проверок на одну заглавную букву, одну цифру, не менее 6 символов и т. д. А где есть добавляю эту букву в конце простого пароля.

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

          Проблемы:
          — надо хранить у себя иероглиф
          — надо запомнить как выглядит иероглиф
          — если чужое устройство надо подключить раскладку или найти в интернете китайский алфавит

          Или подобное не сработает и не стоит так заморачиваться?

          По опыту на многих сайтах не запоминаю пароли, когда заканчивается сессия использую функцию восстановления пароля и по новой меняю пароль на полный бред в пару десятков символов.
          • +2
            Почему бы просто не использовать менеджер паролей вроде KeePass или 1Password? Или любое другое (их много, на любой вкус).
            В этом случае перебор тоже сильно затруднен, т.к. пароли можно генерировать через менеджер и настроить работу так, что они будут действительно сложными и отличающимися на всех сайтах (и не только сайтах).

            В маке, кстати, нечто вроде менеджмента паролей сейчас идет «из коробки», а генерируемые пароли выглядят примерно так: WEp-YtG-6kC-khD
            • 0
              Почему бы просто не использовать менеджер паролей вроде KeePass или 1Password?

              Они хороши, пока база не навернется. А навернуться шифрованная база может очень легко. Проверено на личном печальном опыте с KeePassX.

              Делать резервную копию надо постоянно. А многие делаю её?
              PasswordCommander только делал копию базы, но проект этот, к сожалению, приказал долго жить. Остальные почему-то так и не научились этого делать.
              • +1
                Я отвечал не на ваш комментарий, так что просто подумал, что, если человеку приходит в голову использовать китайский иероглиф в качестве средства, повышающего безопасность его паролей, то, вероятно, ему не будет сильно лень немного заморочиться и настроить автоматические бекапы базы паролей.

                Вообще, менеджеры паролей — тема крайне благодатная для дискуссий.

                Как мне кажется, для среднестатистического пользователя переход с 1-2 паролей на использование менеджера паролей со случайно генерируемыми паролями — это сумасшедший прогресс. В общем-то, для обычных пользователей такой подход решит абсолютное большинство проблем, связанных с паролями. Безопасность самого менеджера паролей — это уже другой вопрос, большинство решений прошли огонь, воду и медные трубы и единственное слабое место в них — это человек, который задает мастер-пароль, а не способы шифрования.

                Какие альтернативы?
                Использовать несколько паролей на всех сайтах и устройствах?
                Использовать стандартный набор паролей с небольшим количеством случайностей в написании?
                Эти два варианта самые распространенные. И самые печальные.

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

                Я не противник или сторонник менеджеров паролей, просто рассуждаю.
                • 0
                  Я просто рассказал причину отказа от менеджера.

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

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

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

                  Я вот всю думаю написать маленькую реализацию некого генератора для себя. Но как обычно лень )

                  Как это примерно выглядит?

                  Маленькая утилита, в виде одного поля для ввода (ну можно с предварительной аутентификацией). Куда вбиваем просто домен, а он уже генерирует в ответ пароль.

                  Как генерируется пароль думаю ясно из сообщения выше: соль (назовем это мастер паролем), некие перестановки мастер-пароля и доменного имени заранее «озвученные», может какие простенькие математические процедуры и MD5.

                  В данном варианте надо будет запомнить алгоритм и мастер пароль, что не очень сложно. И можно воспользоваться будет даже онлайн шифратором в MD5 (есть реализации на JS, который можно залить на свой сайт) или, если позволяют знания и система — командной строкой.

                  Это думаю серьезный плюс над менеджером паролей.

                  Хотя есть один минус всё же у этого: самый известный способ добывания паролей окажется действенным, вам придется рассказать алгоритм/пароль, ибо вы его будете знать :D

                  Это тоже размышлизмы )
                  • 0
                    Серьезный минус по сравнению с хранителями паролей — невозможность применения в системах, где нельзя задать произвольный пароль (допустим он генерируется и сообщается вам), а также в системах, которые предъявляют определенные требования к паролю. Последнее сплошь и рядом: требуют определенную длину, наличие букв разного регистра, цифр, символов. Ваш алгоритм всегда дает на выходе строку из 32 букв и цифр и такой пароль много где не прокатит.
                    • 0
                      Согласен.

                      Но в некоторых случаях можно обрезать пароль по ограничению.
                      Главное чтобы система об этом предупреждала.

                      Или всегда использовать обрезанную версию. 8-12 символов мне кажется достаточно.
                      • +1
                        Обрезать можно, это меньшая из проблем. Можно в конец пароля добавить еще и комбинацию из цифр и букв, которая покрыла бы и другие ограничения. Но все равно найдется какой-нибудь сайт, который потребует, чтобы пароль не начинался с цифры, например. Или чтобы буквы не повторялись.

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

                        А бывает, что надо хранить гораздо больше данных. Например, реквизиты банковской карты: номер карты, владелец, срок действия, CVV, PIN и все эти данные нельзя сгенерировать, они предопределены.

                        А бывает, нужно хранить несколько связанных аккаунтов. Допустим есть у меня хостинг. Это аккаунт у хостера и всякие аккаунты от БД, FTP, SSH.

                        В общем, у меня сотни разных паролей и как жить без хранителя паролей, я не представляю.
                    • 0
                      Насчет утилитки, я такую, например, использую:
                      #!/bin/bash
                      
                      
                      read -p "Master Key:" -s mkey
                      echo
                      
                      read -p "Repeat master Key:" -s mkeyr
                      echo
                      
                      if [ "$mkey" != "$mkeyr" ]
                      then
                      	echo "Master keys not identical"
                      	exit 1
                      fi
                      
                      read -p "Local Key:" -s lkey
                      echo
                      
                      read -p "Repeat local Key:" -s lkeyr
                      echo
                      
                      if [ "$lkey" != "$lkeyr" ]
                      then
                      	echo "Local keys not identical"
                      	exit 1
                      fi
                      
                      echo $(echo -n `echo -n $mkey | sha512sum |head -c128``echo -n $lkey | sha512sum |head -c128` | sha256sum |head -c64)
                      

                      Мастер ключ — собственно единый пароль, локальный ключ — название сайта/ имя шифруемого файла/ что-то ещё
                  • +1
                    Мой хранитель паролей делает резервную копию базы при каждом запуске и хранит какое-то количество последних копий. А сама база лежит в дропбоксе, в котором есть версионность файлов. Заодно разруливаются и конфликтные перезаписи открытой базы.
                    • –3
                      А за тебя в интернете не сидит и от твоего имени комментарии не пишет? :D
                    • +1
                      Почитайте про Mitro. «Секреты» шифруются на стороне клиента с использованием мастер-пароля и зеркалируются на 3 облачных провайдера. При необходимости можно поделиться паролем с кем-нибудь. Проект кросплатформенный и кроссбраузерный (Mozilla Firefox, Chromium), недавно его купил Twitter и открыл исходный код (github). EFF о нём писал недавно. На Android пока не рекомендуют пользоваться, но пилят.
                      • +1
                        GnuPG и текстовые файлы никогда не навернутся. А уж при наличии всяких синхронизаций от DropBox до торрентов вообще решают проблему навсегда.
                        • 0
                          Pocket не то, чтобы супер делает бакапы, но он хранит две копии — на смартфоне и на дропбоксе.

                          Понимаю, что решение не «полное» в смысле историчности бакапа, но таки лучше, чем.

                          Не?
                        • 0
                          В маке, кстати, нечто вроде менеджмента паролей сейчас идет «из коробки»

                          А кто-то делал аудит, того что идет в маке из коробки? А то в принципе во всех браузерах тоже есть хранители паролей, только во многих случаях файл с паролями никак даже не шифровался и пароли в открытом виде хранились. У себя давно юзаю Sticky Password, а уже для его мастер пароля использую метод из простых слов, правда не словарных, и в другой раскладке.
                          • 0
                            А кто-то делал аудит, того что идет в маке из коробки?

                            Насчет аудита сильно сомневаюсь. Но как apple хранит пароли в связке ключей — не секрет. Они используют 256-битное AES шифрование. Пароли хранятся в зашифрованном виде.
                            • 0
                              Они используют 256-битное AES шифрование

                              Это конечно хорошо, но тоже есть свои нюансы. Не всегда для того, чтобы взломать зашифрованное содержимое, нужно ломать именно AES. Зачастую проблема в том, что из-за ошибок может значительно проще найти сохраненный мастер-ключ которым шифровалось содержимое, ну либо другие ошибки не связанные с самим AES.
                            • 0
                              Вот статья про хранение паролей в браузерах. Пишут, что вытащить из Firefox пароли при использовании хорошего мастер-пароля практически нереально.
                              • +1
                                Там ключевая фраза
                                Firefox users are able to set a Master Password in the browser's settings. The problem is that many users likely don't know about this feature.

                                Вы, к примеру, вводили мастер-пароль в Firefox?
                                • 0
                                  «Многим пользователям» и менеджер паролей не нужен, они используют везде 123456. Да, пользуюсь мастер-паролем, хотя плавно перехожу на вышеупомянутый Mitro.
                                  Ставится мастер-пароль в настройках рядом с паролями, полезете в пароли — мимо не пройдёте.
                                  • 0
                                    Ставится мастер-пароль в настройках рядом с паролями, полезете в пароли — мимо не пройдёте.

                                    И многие люди лезут в эти настройки? В том то и дело, оно вроде как и есть, но с пустым мастер-паролем по умолчанию от него толку мало.
                                    Я же, как писал выше предпочитаю Sticky Password, так как обычно пользуюсь Chrome, Firefox и IE 11, и намного проще, чтобы пароли хранились в одном месте, а не в каждом браузере свои. К тому же одна из полезных фич Sticky Password возможность автозаполнения паролей не только в браузерах, но и в других программах.
                                    • 0
                                      Кому нужно — залезет, кому ненужно — он и другие программы для паролей вряд ли будет использовать.

                                      Я согласен, что хранение в одном месте проще, потому и мигрирую. К тому же что-то синхронизация FF в последнее время сбоит.
                                      Mitro не умеет заполнять поля в других программах, впрочем мне такое и не нужно. Зато open source и шифрование на стороне клиента.
                            • 0
                              Довольно давно использую KeePassX под Мак, очень доволен. Храню в основном различные доступы до серверов и т.д. Головной болью было то что не было приложения под iOS, но благодаря Вам, вчера еще раз проверил и нашел. Очень удобное и вроде стабильное.

                              Из минусов немного сложно менять пароли, хотел выработать правило чаще менять везде пароли, но так и не получилось. И главное что если нет под рукой доступа до такого хранилища, то только восстановление пароля поможет, что опять добавляет забот по смене пароля в хранилище. А так можно было использовать и менять пароль вида «yy-mm-異». Вроде все есть под рукой чтоб пройти авторизацию и часто менять пароли. Проблема только если кто-то попросит доступ по телефону, это будет конечно сложно объяснить.
                          • +1
                            Забавная идея.
                            Форкну вас, захотелось поиграться = )
                            • 0
                              Список из 2048

                              Хм. А потом начнут брутить по этому списку.
                              4 слова в пароле из списка в 2048 слов.
                              Какова вероятность брута с перебором по словарю согласно логике комикса?
                            • 0
                              огород минимум носитель матушка

                              Пошел менять пароль на хабре
                              • 0
                                Важно добавить, для того, чтобы на самом деле иметь предсказанную «сложность» (энтропию) пароля 2048^4, обязательно нужно не генерировать несколько раз парольную фразу и выбирать понравившуюся, а брать первую полученную (ну или с другой попытки с фиксированным номером, что дела не меняет). В обратном случае, если ждать понравившейся фразы, энтропия может оказаться значительно меньше — хотя и далеко не факт, что хакер сможет этим воспользоваться.
                                • 0
                                  Согласен, этот метод хорош только тем, что запоминается проще. Но количество комбинаций критически мало, особенно если учесть тот факт, что человек не оперирует словарем в 2000 слов, а есть какие то преференции. Также, он будет выбирать только понравившиеся осмысленные их сочетания. Через год пользования таким сервисом, если фиксировать все выбранные наборы, можно будет составить прекрасную базу для быстрого брутфорса таких паролей :)
                                • +1
                                  1) Стоило бы описать каким образом составляется словарь слов. Например, в словаре не должны содержаться похожие по написанию а там паче однокоренные слова ( «убийца» — «убийство» ). Вообще, хорошо бы ссылку на словарь слов сделать — это не повлияет на безопасность. Вплоть до того, что словарь слов для языка жестко фиксирован и «зашит в стандарте» — все реализации используют один и тот же словарь слов.

                                  2) Самое главное. В ваши сорцы лезть не стану, но в статье стоило бы на этом сделать упор для возможных последователей — если для генерации паролей используется криптографически слабый генератор случайных чисел — то вся концепция накрывается медным тазом
                                  • 0
                                    1) Из частотного словаря русского языка (по ссылке в статье) выбираются самые популярные имена существительные. После этого отбрасываются слова, короче трех букв и длиннее восьми. Однокоренные там есть, это не должно влиять ни на запоминаемость, ни на безопасность.

                                    2) В реализации используется стандартный генератор mt_rand. Попробую изменить генератор на более безопасный.
                                    • +1
                                      3) вообще-то идея когда пароль генерируется на сайте (владелец сайта таким образом имеет все логи) и передается по незащищенному каналу (каждый уважающий себя MitM имеет полный доступ) тоже требует упоминания. Я не пытаюсь дискредитировать идею или в чем-то вас заподозрить. Только обращаю внимание на потенциальные уязвимости подхода. В этом случае лучшим вариантом была бы генерация этого на клиенте с помощью какого-нибудь java-script, а вовсе не php. И опять же — не забывать чем отличается «настоящий рандом» от «псевдо-рандома»

                                      Возвращаясь к словарю. Для английского языка словарь (стандарт де-факто) описан github.com/bitcoin/bips/blob/master/bip-0039.mediawiki (казалось бы, при чем тут биткойн?). Про попытки стандартизовать русский язык я не слышал (впрочем, особо не интересовался)
                                      • 0
                                        Почему только существительные? В оригинале нет такого ограничения.

                                        На прошлой работе ИБ выдавала синтаксически правильные пароли типа «балерина обглодала геолога». Чем они генерили, я не знаю (надеюсь, не руками), но запоминалось легко. Конечно, для сохранения уровня безопасности в дополнение к базе существительных нужна база глаголов такого же размера.
                                        • 0
                                          Во всех реализация встречал только существительные, мне показалось, что так проще запоминать.

                                          А идея с паролей фразой достойная, можно подставлять четыре разных списка слов, в самом простом случае получать что-то вида «умный школа дорого носить».
                                    • 0
                                      Спасибо за статью.
                                      Лично для меня всегда было проще придумать свой алгоритм, запомнить его, а далее самостоятельно генерить пароли.
                                      К примеру, уже лет 5 пользуюсь в качестве генератора паролей таблицей Менделеева, с корректировками вроде: «3я буква всегда заглавная, после слова 3 последние цифры своего мобильного» (Вообще алгоритм сложнее и привязан к сайту\программе, для которой предназначен пароль). Получается что то вроде vaNadium4-50. И мои 8- 10 часто используемых паролей всегда просто вспомнить.
                                      • НЛО прилетело и опубликовало эту надпись здесь
                                        • 0
                                          Этот метод не решает проблемы запоминания, скажем, 1000 паролей. Ну или их одинаковыми делать, что ни разу не есть гуд.
                                          тут без менеджера не обойтись…

                                          Как вариант мастер-пароля — да, неплохая идея.
                                          • 0
                                            А чем плох вариант с использованием, скажем, строки из песни? Тогда «Среди ублюдков шел артист, в кожаном плаще» может правратиться в что-то вроде «Sredi ubliudkov shel artist, в кожаном плаще».
                                            Запоминается, по-моему, элементарно, сложность — зависит от длинны и ухищрений при трансформации…
                                            • –1
                                              То есть, если для типового пароля брутфорсом перебирают байты, то для подбора такого типа пароля нужно просто перебрать комбинации слов из словаря… Мда. Очень надежно.
                                              • 0
                                                На самом деле вполне надежно, так как слов на несколько порядков больше, чем символов которые можно использовать в пароле. И количество комбинаций для 4 слов из 2000 словаря, почти такая как и у пароля из 8 символов (из английских букв в больших и маленьких, и цифр)
                                              • 0
                                                запилил на js:
                                                perevedko.github.io/passwords.html

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