Как я сделал себе менеджер паролей +11


AliExpress RU&CIS

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

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

Первый вариант реализации этой идеи, приходящий на ум — криптографические хеш-функции. На первый взгляд, всё круто: выбираем стойкую функцию (скажем, SHA-3 в 224-битной версии), подаём ей на вход мастер-пароль qwerty и тип аккаунта vk, на выходе мгновенно получаем 56 символов из набора 0123456789abcdef. Я сходу нашёл два подобных проекта: взломанный и потенциально взламываемый. В таком подходе есть большая проблема: криптографические хеш-функции проектируются в том числе с целью быть максимально быстрыми и нетребовательными к ресурсам, и поэтому можно устроить словарный или полный перебор мастер-пароля по перехваченному паролю для одного сайта на CPU (относительно медленно), GPU, FPGA (куда быстрее), ASIC (очень быстро). Для проведения таких атак на популярные алгоритмы хеширования без использования подсаливания можно использовать также радужные таблицы, сильно ускоряющие процесс взлома на CPU.

К счастью, есть другой вариант реализации — функции получения ключей. В двух словах, они выполняют хеширование, но относительно медленно (скажем, одну секунду на обычном процессоре) и с относительно большим потреблением ресурсов (скажем, 16 мегабайт оперативной памяти), чтобы максимально затруднить атаки полным и словарным перебором. Среди знакомых мне современных функций PBKDF2, bcrypt и scrypt лучше всего выглядела scrypt: созданная с учётом опыта первых двух, успешно противостоящая вычислениям на графических процессорах и микросхемах (как FPGA, так и ASIC) и рассчитанная на гибкость при настройке под любые задачи. Я подумывал над реализацией этого проекта, но почему-то задвинул его в долгий ящик. И очень напрасно.

Криптограф Надим Кобеисси сделал как раз такой менеджер паролей npwd на JavaScript (работает как десктопное приложение через Node.JS). Я установил утилиту на компьютер под Linux и под Windows, а также на ноутбук под Linux, начал боевое использование, и мне очень понравилось. Вводишь единственный мастер-пароль и тип аккаунта (например, «twitter») в приложение, и через пару секунд в твоём буфере обмена уже лежит вычисленный сложный пароль конкретно для этого аккаунта, причём взломать твой мастер-пароль (читай: все твои пароли) по паролю для одного аккаунта будет очень, очень сложно.

Но была и проблема. Версия под Windows действительно выдавала пароль через пару секунд, а вот под Linux (в том числе на том же самом компьютере!) для вычислений требовалось уже секунд 15, что напрягало. Сначала я просто уменьшил одну константу, сделав мастер-пароль менее защищённым, но потом я подумал — а почему бы не переписать приложение на C, ведь наверняка будет работать гораздо быстрее! Особенно меня подзадоривала мысль, что у меня давно был замысел этого проекта, но я стормозил, и кто-то реализовал его до меня.

Через несколько дней неспешной работы я сделал свой менеджер паролей cpwd, полностью совместимый с оригиналом. Это было весело! После небольшой оптимизации мне удалось достичь желанной высокой скорости работы. Портировать cpwd под Windows я не пробовал, но это должно быть несложно. На GitHub-странице проекта я собрал коллекцию ссылок на подобные проекты в академическом мире и за его пределами – оказалось, что идея вообще-то весьма стара.

Конечно, это не серебряная пуля, но it works for me. В процессе использования я наткнулся на проблему: некоторые сайты имеют интересные требования к паролям типа «не более 20 символов», «обязательно встречается большая буква, маленькая буква, цифра и спецсимвол», в результате сгенерированный npwd/cpwd пароль иногда требует доработки руками перед вводом. К счастью, таких сайтов немного.

Оригинал опубликован в моём блоге 7.08.15. Прошло 5 лет, а я до сих пор пользуюсь этой утилиткой.




Комментарии (14):

  1. lrrr11
    /#22350084 / +1

    Среди знакомых мне современных функций PBKDF2, bcrypt и scrypt лучше всего выглядела scrypt

    хотел написать про Argon2, но


    Оригинал опубликован в моём блоге 7.08.15

    понятно, его тогда просто не было)

  2. dion
    /#22350122 / +1

    Кроме указанной проблемы с требованиям к паролям, совершенно не ясно, что делать с сервисами, просящими сменить пароль. Это может быть как тупой таймер (менять пароль каждые XX дней), так и принудительная смена пароля из-за утечек и подобного...

    • posthedgehog
      /#22350210

      Всё так! Можно заменить «twitter» на «twitter2» и т.д., но это очень не удобно.

      • dion
        /#22350226

        Вот вот. Закончится путаницей вроде facebook13 или twitter23. И нужен будет другой менеджер для этих суффиксов.

    • vmkazakoff
      /#22350222 / +1

      Вводить как одну из переменных номер? По умолчанию будет twitter0, но после очередной утечки сменить на twitter1 — с учётом что это хеш то этот один символ даст очень большое отличие. И надо будет через время просто вспомнить сколько примерно раз менял пароль (ну и перебрать несколько вариантов, если уж совсем никак).


      И ещё одна проблема — смена названий. Miro раньше назывался realtime board и я лично вообще случайно узнал что это оказывается один проект (думал два разных). Или ещё был сервис удобный для быстрых видео звонков без приложений appear.in с удобными короткими ссылками — отсудили домен. Помню ещё сервис для создания мультиков с готовыми шаблонами — тоже переименоваться и сменил домен… Вот потом мороки вспоминать как он раньше назывался...


      Ну и есть ещё кейс когда у человека несколько учёток на одном сервисе. Тоже, видимо, надо или нумерацию подключать, или ещё логин как переменную.

  3. shadovv76
    /#22350160

    зачастую программы-менеджеры откровенно плохо защищены

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

    • istepan
      /#22350258

      есть базовая комбинация клавиш на клавиатуре

      Я встрял с этим когда надо было ввести на устройстве со своей уникальной раскладкой)
      Пришлось учить символы.

      • shadovv76
        /#22350378

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

  4. istepan
    /#22350194 / +1

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


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

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

    Стараюсь пароли генирировать через него. Кроме тех что приходится иногда вводить вручную.

    • HectorPrima
      /#22353192

      110Mb занимает. Чем он свежий кроме размера в 20 раз большего?

  5. Revertis
    /#22350852 / +1

    После публикаций о vPass я решил пофиксить все высказанные там опасения и создал расширение для браузера.
    Итого:
    0. В качестве алгоритма взят pbkdf2 со 100 итерациями, но этот шаг повторяется несколько раз, чтобы в результате была хотя бы одна цифра, одна малая буква и одна большая.
    1. Пароль нельзя подсмотреть или снять скриншотом — показываются только первые 4 знака, чтобы визуально понимать что сгенерировалось, не допущена ли ошибка.
    2. Пароль не проходит через буфер обмена, а вставляется напрямую в поле, выделенное перед активацией расширения (F8).
    3. Пароль зависит ещё и от соли, которая хранится в настройках расширения и не набирается вручную каждый раз — защита от кейлоггеров.
    4. Чтобы не носить с собой браузер я сделал и приложение под Андроид — оно не имеет разрешений использовать сеть, так что ничего не утечёт в сеть.

  6. fndrey357
    /#22351578

    Пароли/логины
    Три почты отечественных
    Одна почта импортная.
    Банк 1
    Банк 2
    Квартиры своя, родителей — электрика. вода. тепло
    комп на работе
    комп дома
    Куча форумов.
    4 компа с которых работаю
    В общем просто лежат в файлике с паролем.

  7. belonesox
    /#22352476

    В процессе использования я наткнулся на проблему: некоторые сайты имеют интересные требования к паролям

    А это на самом деле — главное. Даже один из самых первых JS-хеширующих-букмарклетов (лет 12 ему, если не больше)
    https://github.com/chriszarate/supergenpass, сразу заморачивался этой проблемой (насколько помню, продолжал хешировать пока не выпадет большая+малая+цифра).

  8. dmytzo
    /#22353220 / +1

    Буквально на прошлой неделе решил сделать что-то подобное. Но по моей задумке, на вход подается мастер пароль + ресурс + юзернейм.
    Это как раз решает данный кейс:

    Ну и есть ещё кейс когда у человека несколько учёток на одном сервисе. Тоже, видимо, надо или нумерацию подключать, или ещё логин как переменную.

    А по поводу суффиксов:
    Всё так! Можно заменить «twitter» на «twitter2» и т.д., но это очень не удобно.

    Первая идея была — сделать генерацию по цепочке. Т.е. первая генерация — генерация с введенными данными, вторая генерация — хеш от первого пароля и тд. Но проблема остается.

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

    В интерфейсе можно сделать 2 кнопки: «Сгенерировать новый» и «Сгенерировать текущий».
    «Сгенерировать новый» — создаст в бд новую запись с текущим таймстемпом и сгенерирует на основе этих данных пароль.
    «Сгенерировать текущий» — сгенерирует пароль на основе введены данных + таймстемп с последней записи для данного ресурса и юзернейма.
    Но это уже противоречит задумке — менеджер паролей без бд…