Свободный менеджер паролей LessPass работает на чистой функции



    Хранение уникальных паролей для всех сайтов и приложений — целое искусство. Невозможно запомнить сотню длинных паролей с высокой энтропией. Может быть, в мире есть десяток высокоразвитых аутистов, способных на такое, не больше. Остальным людям приходится использовать технические трюки. Самый распространённый вариант — записать все пароли в один файл, который защищён мастер-паролем. По такому принципу работает большинство парольных менеджеров.

    У этого способа много преимуществ, но есть два главных недостатка: 1) трудно синхронизировать пароли между устройствами; 2) нужно всегда иметь в распоряжении сам файл с паролями. То есть потерял файл с паролями — и до свидания.

    Новый парольный менеджер LessPass с открытым исходным кодом лишён этих недостатков, потому что работает на чистой детерминированной функции. У него есть другие недостатки, конечно. Об этом ниже. Сначала о достоинствах.

    Концепция


    Концепция LessPass заключается в том, что регенерация одноразовых паролей происходит на лету при помощи чистой функции, которая выдаёт детерминированные значения каждый раз при расчёте каждого уникального пароля.

    На вход функции подаются четыре аргумента:

    • мастер-пароль
    • логин на сайте
    • адрес сайта
    • опции генерации пароля

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

    Как это выглядит.



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

    Разработчик программы Гийом Винсент (Guillaume Vincent) постарался реализовать безопасность, насколько он её понимает. Какая безопасность нужна для детерминированной функции? В первую очередь — чтобы по результату её работы нельзя было определить все её аргументы, тем более что некоторые аргументы уже известны злоумышленнику, как и сама функция.

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

    Для защиты мастер-пароля от брутфорса вычисление уникальных паролей LessPass прогоняет 8192 итерации функции PBKDF2 с хэш-функцией SHA-256.



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

    Теперь, чтобы «вспомнить» уникальный пароль для конкретного сайта — просто запускаем программу LessPass. Это крошечная программа состоит всего из 109 строчек.

    Код программы
    import crypto from 'crypto';
    
    module.exports = {
        encryptLogin: _encryptLogin,
        renderPassword: _renderPassword,
        createFingerprint: createFingerprint,
        _deriveEncryptedLogin,
        _getPasswordTemplate,
        _prettyPrint,
        _string2charCodes,
        _getCharType,
        _getPasswordChar,
        _createHmac
    };
    
    function _encryptLogin(login, masterPassword, {iterations = 8192, keylen = 32}={}) {
        return new Promise((resolve, reject) => {
            if (!login || !masterPassword) {
                reject('login and master password parameters could not be empty');
            }
            crypto.pbkdf2(masterPassword, login, iterations, keylen, 'sha256', (error, key) => {
                if (error) {
                    reject('error in pbkdf2');
                } else {
                    resolve(key.toString('hex'));
                }
            });
        })
    }
    
    function _renderPassword(encryptedLogin, site, passwordOptions) {
        return _deriveEncryptedLogin(encryptedLogin, site, passwordOptions).then(function (derivedEncryptedLogin) {
            const template = passwordOptions.template || _getPasswordTemplate(passwordOptions);
            return _prettyPrint(derivedEncryptedLogin, template);
        });
    }
    
    function _createHmac(encryptedLogin, salt) {
        return new Promise(resolve => {
            resolve(crypto.createHmac('sha256', encryptedLogin).update(salt).digest('hex'));
        });
    }
    
    function _deriveEncryptedLogin(encryptedLogin, site, passwordOptions = {length: 12, counter: 1}) {
        const salt = site + passwordOptions.counter.toString();
        return _createHmac(encryptedLogin, salt).then(derivedHash => {
            return derivedHash.substring(0, passwordOptions.length);
        });
    }
    
    function _getPasswordTemplate(passwordTypes) {
        const templates = {
            lowercase: 'vc',
            uppercase: 'VC',
            numbers: 'n',
            symbols: 's',
        };
        let template = '';
        for (let templateKey in templates) {
            if (passwordTypes.hasOwnProperty(templateKey) && passwordTypes[templateKey]) {
                template += templates[templateKey]
            }
        }
        return template;
    }
    
    function _prettyPrint(hash, template) {
        let password = '';
    
        _string2charCodes(hash).forEach((charCode, index) => {
            const charType = _getCharType(template, index);
            password += _getPasswordChar(charType, charCode);
        });
        return password;
    }
    
    function _string2charCodes(text) {
        const charCodes = [];
        for (let i = 0; i < text.length; i++) {
            charCodes.push(text.charCodeAt(i));
        }
        return charCodes;
    }
    
    function _getCharType(template, index) {
        return template[index % template.length];
    }
    
    function _getPasswordChar(charType, index) {
        const passwordsChars = {
            V: 'AEIOUY',
            C: 'BCDFGHJKLMNPQRSTVWXZ',
            v: 'aeiouy',
            c: 'bcdfghjklmnpqrstvwxz',
            A: 'AEIOUYBCDFGHJKLMNPQRSTVWXZ',
            a: 'AEIOUYaeiouyBCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz',
            n: '0123456789',
            s: '@&%?,=[]_:-+*$#!\'^~;()/.',
            x: 'AEIOUYaeiouyBCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz0123456789@&%?,=[]_:-+*$#!\'^~;()/.'
        };
        const passwordChar = passwordsChars[charType];
        return passwordChar[index % passwordChar.length];
    }
    
    function createFingerprint(str) {
        return new Promise(resolve => {
            resolve(crypto.createHmac('sha256', str).digest('hex'))
        });
    }

    Генерация паролей работает в виде скрипта на сайте LessPass, или на клиентском компьютере. Выпущены соответствующие расширения для Chrome и для Firefox. Скрипт генератора можно запустить и в локальном облаке. Например, с помощью локального облака Cozy.

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

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

    Второй недостаток — вы не можете нормально и удобно поменять пароль для конкретного сайта. Для этого придётся изменить один из параметров генерации паролей (Counter). Впоследствии придётся помнить, какой конкретно параметр использовался для каждого сайта. Где единица, где двойка, где тройка, и так далее. Кроме того, нужно помнить уникальные требования каждого сайта к паролям. Например, какие-то банковские приложения могут ограничить пароль только цифрами и длиной в шесть цифр. Для решения этой проблемы в LessPass реализованы профили для сайтов. В профиле хранитеся вся информация, необходимая для генерации пароля, кроме мастер-пароля.


    Профили в LessPass

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

    Ситуация ухудшается тем, что в данной конкретной реализации LessPass использует всего 8192 итерации PBKDF2-SHA256. По мнению специалистов, этого крайне недостаточно для надёжной защиты от брутфорса на GPU. Ещё несколько лет назад рекомендовалось минимум 100 000 итераций, а вычислительная мощность брутфоса примерно удваивается каждый год. Так что будем считать, что нынешняя реализация LessPass — просто демонстрационная версия, доказательство работоспособности концепции.

    LessPass — не единственный детерминированный менеджер паролей, работающий на чистой функции. Есть и другие аналогичные программы, в том числе Master Password App и Forgiva. У всех этих программ те же недостатки, о которых упоминалось выше. К тому же, в них нельзя импортировать свои старые пароли, так что при миграции на такую программу придётся заново генерировать все пароли.

    Несмотря на все недостатки, генератор детерминированных паролей на чистой функции — интересная концепция. Возможно, кому-то именно такой парольный менеджер покажется наиболее удобным.
    Support the author
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 38

      +1
      На Хабре уже пару лет назад автор писал о подобном генераторе, который работает на vpass.info.
      А я давненько на его основе сделал расширение для ФФ: https://addons.mozilla.org/ru/firefox/addon/vpass-password-generator/
      На сайте, где хотите залогиниться, вводите логин, переходите на поле пароля, там нажимаете F9, в появившемся окошке вводите только свой мастер-пароль и нажимаете Enter. Сгенерированный пароль вводится в поле пароля.
        +1
        А еще есть supergenpass, он раньше всех появился (в то время назывался genpass).
          0
          Я тоже аналогичный генератор себе написал весной 2013-ого года. Rupass, функционала немного, но работает же. Пользовался им несколько лет, но потом узнал про keepassx.

          Все-таки недостатки файла с паролями нивелируются шифрованием жесткого диска, автоблокировкой по неактивности и синхронизацией в свое облако. А у генератора проблем нерешаемых много: сайты, которые генерят логины/пароли сами, сайты с несколькими доменами, невозможность сменить мастер-пароль, невозможно сохранить чужой пароль.
            0
            да, SuperGenPass наше всё!
          +13
          Четвертый и главный недостаток: вам надо помнить все логины, либо использовать один единственный логин и один адрес почты на вообще всё
            +2
            А если есть несколько аккаунтов на одном сайте, то вообще беда
              0
              Зачем? Главное ведь не lesspass а сама идея.

              Можно написать себе свой менеджер или плагин, в котором будет сохраняться и сайт и логин, а пароль генериться по первому, по второму или по обоим вместе + соль. В общем додумать можно.
              +2
              1) трудно синхронизировать пароли между устройствами; 2) нужно всегда иметь в распоряжении сам файл с паролями. То есть потерял файл с паролями — и до свидания.

              Обе проблемы решаются с помощью облачных хранилищ. База у всех приличных менеджеров паролей хорошо зашифрована.
                0
                Вот только если это не ваш личный менеджер паролей — на 100% ему доверять нельзя. Кто знает — все ли там по честному или оставлены бэкдоры для себя или еще кого-то. А написать свой личный менеджер паролей смогут не все.
                  0
                  К KeePass, если не изменяет память, можно писать плагины с собственной реализацией шифрования.
                  На худой конец, можно банально шифровать с помощью открытого 7-zip.
                +7
                Блин, читал-читал статью, и только когда пролистал по новой понял, что речь не про LastPass!
                  +1
                  Так это ж хорошо.
                  +9
                  Хе, что ж получается…
                  плюсы: у злоумышленника нет возможности украсть у вас файл с паролями, потому что его нет!
                  недостатки: для брутфорса вашего пароля злоумышленнику не нужен никакой файл.

                    +2
                    Ага, для того, чтобы сбрутить пароль, ему нужно… сбрутить пароль :)
                      +1
                      Да, но достаточно его сбрутить на одном сайте, чтобы получить доступ ко всем.
                        0
                        Ага, только ему еще нужно догадаться, что вы используете какой-то из генераторов :)
                          0
                          Если атакуем конкретного человека то это, скорее всего, известно. Заманили его к себе на сайт и попросили зарегистрироваться — вот тебе и материал для работы сразу. Или человек проговорился где-то что использует подобную штуку… На хабре в комментариях, например.
                      0
                      Из за PBKDF2, брутить придется долго
                      +1
                      При частичной смене URL сайта, будет генерироваться неправильный пароль
                        +1
                        При наличии на одном сайте 2-х сервисов с разными паролями — вообще беда
                        0
                        а если сайт сменил адрес|домен, заново регаться?
                          +1
                          Вводить старый домен.
                          0
                          База KeePass2 в облачном хранилище с мастер-паролем и ключом. Для мобильных устройств не подойдет, но для ноутбуков и ПК — вполне.
                            +5
                            Почему для мобильных не подойдёт? База и ключ в облаке (скажем, том же Я.Диске), прекрасно работает на и на ПК, и на ноутбуке, и на смартфоне (Android).
                              +3
                              Подтверждаю, база KeePass2 лежащая в облаке (в моем случае домашний owncloud) прекрасно работает на всех платформах (Windows, Linux, Android, IOS)
                                0
                                Вот у меня работает, но так как я настраивал на число циклов хеширования пароля на задержку в 1 сек, то на телефоне задержка вышла более 10 сек.
                              0
                              Интересно, словом «свободный» было переведено «LessPass is open-source» или «LessPass is free
                              and always will be».
                                0
                                Полные исходники — в статье же, под спойлером. Абзацем ниже синей картинки со схемой генерации.
                                Другой вопрос, что open source не всегда равно free. Но сходить на сайт автора за лицензионным соглашением тоже никто не мешает.
                                +1
                                есть два главных недостатка: 1) трудно синхронизировать пароли между устройствами;

                                в 2016 уже не трудно

                                2) нужно всегда иметь в распоряжении сам файл с паролями.

                                не является недостатком как следствие п. 1
                                • UFO just landed and posted this here
                                    +1
                                    — Пароли рекомендуют менять раз в несколько месяцев. Некоторые сайты настойчиво «предлагают» сменить пароли. Как тут быть?
                                    — Есть сайты где спец символы не поддерживаются. Нужно помнить состав типов символов для каждого сайта.
                                    — Скомпрометировал мастер пароль. В нормальном менеджере перешифровал БД, что делать в этой ситуации с этим менеджером?
                                      0
                                      На второй вопрос есть ответ в тексте.
                                        0
                                        1. Изменить counter. Например, просто поставить его в 201611 и менять каждый месяц для важных паролей.
                                        3. Если делать с синхронизацией, как предлагают многие, то после компрометации масетр-пароля всё равно надо менять все пароли.
                                      • UFO just landed and posted this here
                                          0
                                          Заметить, что идёт атака, может сервер. Также сервер может сообщить пользователю о свежих неудачных попытках войти и их количестве за последний час (чтобы не сообщать о каждом неудачном входе), сообщается о первом неудачном входе и следующее сообщение — через час о количестве за час. И предлагает что-то сделать с этим.
                                          • UFO just landed and posted this here
                                              0
                                              > более менее безопасно
                                              Надеюсь, среди разработчиков подобного рода софта не многие мыслят подобным образом.
                                              0

                                              Эээх — давно то было… Наша компания придумала такое же — вот только в архивах нашел https://www.helpnetsecurity.com/2006/03/20/amust-software-announces-amust-1-password/


                                              Мы решили проблему с запоминанием логинов — генерили файлик, который открывался по мастер паролю и синкали его в Gmail/Hotmail/etc просто как драфт письма
                                              Если пользователь находился вдали от родного компьютера с софтом просили его зайти в его почту взять текст из этого драфта и закопипастить на страничку, а далее расшифровывали все с мастер паролем с помощью чистого ДжаваСкрипта.

                                              Only users with full accounts can post comments. Log in, please.