Хранение уникальных паролей для всех сайтов и приложений — целое искусство. Невозможно запомнить сотню длинных паролей с высокой энтропией. Может быть, в мире есть десяток высокоразвитых аутистов, способных на такое, не больше. Остальным людям приходится использовать технические трюки. Самый распространённый вариант — записать все пароли в один файл, который защищён мастер-паролем. По такому принципу работает большинство парольных менеджеров.
У этого способа много преимуществ, но есть два главных недостатка: 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. У всех этих программ те же недостатки, о которых упоминалось выше. К тому же, в них нельзя импортировать свои старые пароли, так что при миграции на такую программу придётся заново генерировать все пароли.
Несмотря на все недостатки, генератор детерминированных паролей на чистой функции — интересная концепция. Возможно, кому-то именно такой парольный менеджер покажется наиболее удобным.
Комментарии (38)
KennyGin
07.11.2016 22:06+13Четвертый и главный недостаток: вам надо помнить все логины, либо использовать один единственный логин и один адрес почты на вообще всё
saboteur_kiev
08.11.2016 01:19Зачем? Главное ведь не lesspass а сама идея.
Можно написать себе свой менеджер или плагин, в котором будет сохраняться и сайт и логин, а пароль генериться по первому, по второму или по обоим вместе + соль. В общем додумать можно.
dartraiden
07.11.2016 22:09+21) трудно синхронизировать пароли между устройствами; 2) нужно всегда иметь в распоряжении сам файл с паролями. То есть потерял файл с паролями — и до свидания.
Обе проблемы решаются с помощью облачных хранилищ. База у всех приличных менеджеров паролей хорошо зашифрована.alexvoz
08.11.2016 00:58Вот только если это не ваш личный менеджер паролей — на 100% ему доверять нельзя. Кто знает — все ли там по честному или оставлены бэкдоры для себя или еще кого-то. А написать свой личный менеджер паролей смогут не все.
dartraiden
08.11.2016 03:37К KeePass, если не изменяет память, можно писать плагины с собственной реализацией шифрования.
На худой конец, можно банально шифровать с помощью открытого 7-zip.
DenimTornado
07.11.2016 22:17+7Блин, читал-читал статью, и только когда пролистал по новой понял, что речь не про LastPass!
Sild
07.11.2016 22:20+9Хе, что ж получается…
плюсы: у злоумышленника нет возможности украсть у вас файл с паролями, потому что его нет!
недостатки: для брутфорса вашего пароля злоумышленнику не нужен никакой файл.
Revertis
07.11.2016 23:18+2Ага, для того, чтобы сбрутить пароль, ему нужно… сбрутить пароль :)
Loki3000
07.11.2016 23:30+1Да, но достаточно его сбрутить на одном сайте, чтобы получить доступ ко всем.
Revertis
08.11.2016 08:56Ага, только ему еще нужно догадаться, что вы используете какой-то из генераторов :)
Loki3000
08.11.2016 09:26Если атакуем конкретного человека то это, скорее всего, известно. Заманили его к себе на сайт и попросили зарегистрироваться — вот тебе и материал для работы сразу. Или человек проговорился где-то что использует подобную штуку… На хабре в комментариях, например.
timelle
08.11.2016 00:52База KeePass2 в облачном хранилище с мастер-паролем и ключом. Для мобильных устройств не подойдет, но для ноутбуков и ПК — вполне.
chesterset
08.11.2016 01:00+5Почему для мобильных не подойдёт? База и ключ в облаке (скажем, том же Я.Диске), прекрасно работает на и на ПК, и на ноутбуке, и на смартфоне (Android).
nicknishim
08.11.2016 09:48+3Подтверждаю, база KeePass2 лежащая в облаке (в моем случае домашний owncloud) прекрасно работает на всех платформах (Windows, Linux, Android, IOS)
sumanai
08.11.2016 18:55Вот у меня работает, но так как я настраивал на число циклов хеширования пароля на задержку в 1 сек, то на телефоне задержка вышла более 10 сек.
anitspam
08.11.2016 07:42Интересно, словом «свободный» было переведено «LessPass is open-source» или «LessPass is free
and always will be».K0styan
08.11.2016 13:56Полные исходники — в статье же, под спойлером. Абзацем ниже синей картинки со схемой генерации.
Другой вопрос, что open source не всегда равно free. Но сходить на сайт автора за лицензионным соглашением тоже никто не мешает.
somniator
08.11.2016 09:41+1есть два главных недостатка: 1) трудно синхронизировать пароли между устройствами;
в 2016 уже не трудно
2) нужно всегда иметь в распоряжении сам файл с паролями.
не является недостатком как следствие п. 1
ruzhovt
08.11.2016 10:31Недостатки сильно превышают преимущества.
Лучше иметь зашифрованую базу с паролями случанйыми чем отсутствие базы, но всем известную функцию для генерации паролей.
При утрате мастер-пароля в первом случае последствия не такие плачевные как при втором варианте, так как нужно еще и базу паролей украсть, а доступ к базе паролей естественно идет по https или другому шифрованнному каналу, и сам контент базы отдается только клиентам с правильными кукакми / хидерами (которые опять же получаются только первый раз при запуске приложения и вводе пароля, что обычно делается из безопсного места/сети)
Украсть/увидеть мастер пароль довольно просто. Украсть куки из хттпс канала куда сложнее.
n00b1k
08.11.2016 11:23+1— Пароли рекомендуют менять раз в несколько месяцев. Некоторые сайты настойчиво «предлагают» сменить пароли. Как тут быть?
— Есть сайты где спец символы не поддерживаются. Нужно помнить состав типов символов для каждого сайта.
— Скомпрометировал мастер пароль. В нормальном менеджере перешифровал БД, что делать в этой ситуации с этим менеджером?dpantele
08.11.2016 23:591. Изменить counter. Например, просто поставить его в 201611 и менять каждый месяц для важных паролей.
3. Если делать с синхронизацией, как предлагают многие, то после компрометации масетр-пароля всё равно надо менять все пароли.
guai
08.11.2016 13:48а после того, как надо было поменять пароль на сайте на новый, придется запоминать настройки генерации :)
для каждого сайта
mafia8
08.11.2016 14:49Заметить, что идёт атака, может сервер. Также сервер может сообщить пользователю о свежих неудачных попытках войти и их количестве за последний час (чтобы не сообщать о каждом неудачном входе), сообщается о первом неудачном входе и следующее сообщение — через час о количестве за час. И предлагает что-то сделать с этим.
ruwebstyle
08.11.2016 15:55Нужно общее между lesspass и lastpass.
Хранить сайты и логины к ним централизованно (с возможностью автопрописки логина в поле логина), а пароли генерировать каждый раз как сейчас. Тогда будет и более менее удобно, и более менее безопасно.
Если к этому еще прикрутить возможность держать сайты и логины у себя на сервере, в обычной базе MySQL, то цены не будет.ESP
08.11.2016 20:02> более менее безопасно
Надеюсь, среди разработчиков подобного рода софта не многие мыслят подобным образом.
avas
08.11.2016 20:25Эээх — давно то было… Наша компания придумала такое же — вот только в архивах нашел https://www.helpnetsecurity.com/2006/03/20/amust-software-announces-amust-1-password/
Мы решили проблему с запоминанием логинов — генерили файлик, который открывался по мастер паролю и синкали его в Gmail/Hotmail/etc просто как драфт письма
Если пользователь находился вдали от родного компьютера с софтом просили его зайти в его почту взять текст из этого драфта и закопипастить на страничку, а далее расшифровывали все с мастер паролем с помощью чистого ДжаваСкрипта.
Revertis
На Хабре уже пару лет назад автор писал о подобном генераторе, который работает на vpass.info.
А я давненько на его основе сделал расширение для ФФ: https://addons.mozilla.org/ru/firefox/addon/vpass-password-generator/
На сайте, где хотите залогиниться, вводите логин, переходите на поле пароля, там нажимаете F9, в появившемся окошке вводите только свой мастер-пароль и нажимаете Enter. Сгенерированный пароль вводится в поле пароля.
ValdikSS
А еще есть supergenpass, он раньше всех появился (в то время назывался genpass).
vtyulb
Я тоже аналогичный генератор себе написал весной 2013-ого года. Rupass, функционала немного, но работает же. Пользовался им несколько лет, но потом узнал про keepassx.
Все-таки недостатки файла с паролями нивелируются шифрованием жесткого диска, автоблокировкой по неактивности и синхронизацией в свое облако. А у генератора проблем нерешаемых много: сайты, которые генерят логины/пароли сами, сайты с несколькими доменами, невозможность сменить мастер-пароль, невозможно сохранить чужой пароль.
glazunoff
да, SuperGenPass наше всё!