Пользователь
0,0
рейтинг
24 апреля 2012 в 14:34

Разработка → FortNotes — онлайн менеджер паролей из песочницы

День добрый.
Хочу поделиться проектом, который недавно закончил. Надеюсь кому-то пригодится.
Все, кто пользуется интернетом длительное время, наверняка накопили большое количество различных приватных данных, таких как логины и пароли от сайтов, почтовых ящиков, серверов и баз данных. У кого-то меньше, у кого-то больше, но такие данные есть у всех. Можно хранить это на клочках бумаги, стикерах на мониторе, в блокноте на тумбочке или в файле на рабочем столе. Многие догадываются что это не очень безопасно: кто-то может подсмотреть или банально можно потерять эти драгоценные данные, но обычно редко кто пытается что-то с этим сделать.
Интернет очень плотно вошел в нашу жизнь и было бы неплохо иметь возможность упорядочить и обезопасить свои данные. Даже если не хранить в банках миллионы и не переживать, что кто-то украдет пароль от банковского счета, — это не значит, что будет приятна утеря доступа к почте, wm-киперу или фейсбуку. Личная переписка, деловые контакты, фотографии, секретная информация разного вида — всё это не должно быть доступно никому, кроме владельца.

Общее описание системы


FortNotes — это Форт Нокс для пользовательских данных. Технология в основе этого проекта — BlackBox, чёрный ящик или зашифрованный контейнер. Все записи, создаваемые на этом сайте, немедленно шифруются прямо в браузере с помощью AES (симметричный алгоритм блочного шифрования, принятый в качестве стандарта шифрования правительством США) и только после этого отправляются на сервер уже в зашифрованном виде. Это означает, что никто, кроме владельца данных, не имеет к ним доступа. Ни перехват данных интернет-соединения, ни изучение зашифрованного контейнера излишне любопытной администрацей сайта не позволят получить доступ к исходным данным. Без пользовательского пароля это будет просто бессмысленная мешанина символов. Чёрный ящик расшифровывается в реальную информацию только при входе на сайт FortNotes и вводе пароля. Таким образом пользователи не доверяют хранение своих секретных данных непонятно кому: сервер FortNotes хранит только зашифрованные чёрные ящики и ничего более, никакой информации в открытом виде. Дальше пользовательского компьютера и браузера не уходит даже логин, под которым проходит регистрация в системе. Абсолютно всё шифруется перед отправкой на сервер. Когда нужны данные — шлётся запрос, закачивается крипто-контейнер и происходит расшифровка. Процесс автоматизирован и прозрачен: требуется только предварительный ввод пароля.

Going deeper


Регистрация


Для регистрации в системе требуется только логин и пароль, которые перед отправкой на сервер преобразовываются в sha256-хеш, что по сути делает регистрацию анонимной. Вместо имен пользователей и их паролей в базе хранятся символьные последовательности вида «a9dc602f9d82bc6720b2b4bb016edcacf7da4b2b453a466b742da743f3cba15d». На сервере не хранятся никакие данные, которые могли бы идентифицировать пользователей. По этой же причине не запрашивается e-mail пользователя, так что восстановление логина и пароля невозможно. Высокий уровень безопасности накладывает определенные требования: нет никаких бекдоров, никаких «восстановлений забытых паролей». Это означает, что утеря этого пароля равнозначна утере всей базы секретных пользовательских данных. Модальное окно регистрации настойчиво акцентирует на этом внимание:



Для верификации регистрации используется капча:



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



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

В правом верхнем углу экрана доступны две команды:
  • Lock позволяет немедленно зашифровать все открытые данные, стереть из памяти пароль и заблокировать экран до тех пор, пока не будет введен пароль. Важно помнить, что если в этот момент редактировались какие-либо данные заметки и они не были сохранены, то при данной блокировке эти изменения так и останутся только в браузере и не попадут на сервер, пока пользователь явно не сохранит заметку.
  • Exit выполняет полный выход из системы с очисткой пароля из памяти, удалением всех пользовательских кешей и сессии на сервере, после чего перенаправляет на домашнюю страницу проекта.

Создание и редактирование заметок


Основная единица информации в системе это note — заметка. Заметки могут быть разных типов. Для создания заметок имеется с десяток основных типов, оформленных в виде шаблонов. С их помощью в один клик можно получить заметку типа «почтовый ящик», «сайт», «jabber аккаунт», «ssh/ftp сервер» и т.д. Типы не статичны, но об этом чуть позже. Список типовых шаблонов для заметок:



Каждая заметка состоит из набора полей (entry), которые представляют из себя конечные поля ввода информации, и списка тегов, разделенных пробелом. Так, например, заметка типа «skype» состоит из трех полей: skype name (имя скайп-аккаунта), password (пароль), comments (необязательное поле комментариев) и выглядит следующим образом:



Поля, в свою очередь, тоже делятся по типам: простой однострочный текст, e-mail, URI (для адресов типа сайтов), пароль, многострочный текст, html.
Деление по типам для полей позволяет добавлять различные вспомогательные операции: например, для поля типа «пароль» становится доступной функция генерации случайного пароля заданной длины, для поля адреса при вводе URL производится попытка получить описание сайта и иконки для дальнейшего использования.

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



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



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



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



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



При редактировании заметки возможно выполнить быстрое сохранение с помощью комбинации клавиш Ctrl + Enter.
Помимо сохранения доступны две специальные команды — дублирование текущей заметки и создание новой заметки аналогичной текущей, но с пустыми полями. Это будет удобно при создании серии однотипных заметок.

Поиск и фильтрация


Поиск на серверной стороне осуществляется с помощью тегов, перечисленных через пробел в строке поиска. Использование в поиске тега со знаком минус перед ним выводит список заметок, где такой тег не встречается. Помимо пользовательских тегов, создаваемых при добавлении заметок, есть набор системных тегов для получения списка удаленных заметок, заметок без тегов или фильтрации по времени последнего доступа. Такие теги доступны в строке поиска после ввода символа двоеточия ":". В примере ниже показан результат поиска записей за последний месяц, где встречаются теги site, work и dev, но не встречается тег php:



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

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



Поиск по тегам возвращает первые 20 заметок. При необходимости получить полный список, можно воспользоваться соответствующей ссылкой load all. Там же присутствуют ссылки для выделения всех заметок, снятия выделения и инвертирования. Для того чтобы начать работу с заметкой, достаточно щёлкнуть по ней мышью, после чего строка будет отмечена галочкой и подсвечена зеленым цветом, а заметка будет открыта в режиме редактирования. Также возможно отметить галочкой одну и более заметок, щёлкнув по нужной строке с зажатой клавишей Ctrl. Аналогично работе в файловых менеджерах работает выделение заметок при нажатой клавише Shift — выделяет все элементы между двух щелчков мышью. Над выделенными галочками заметками можно проводить общие операции: удаление или восстановление удаленных. Для перехода в режим восстановления удаленных заметок можно воспользоваться системным тегом :deleted. Также возможность перейти к восстановлению присутствует в подсказке, всплывающей сразу же после удаления выбранных заметок.
Если в строке поиска будут обнаружены слова, не являющиеся тегами, то они будут использованы для дополнительной фильтрации всех загруженных в список заметок.



Техническая сторона


Языки разработки — PHP и Javascript. Второго ощутимо больше, потому как основная работа идет на клиентской стороне. Роль серверной стороны сводится к регистрации/авторизации и обработке AJAX запросов на сохранение/получение данных и их поиск. Для AES шифрования на клиенте по 256 битному ключу используется замечательная библиотека SJCL (Stanford Javascript Crypto Library).

Клиентская сторона представляет собой по сути веб-приложение, работающее без перезагрузок, и состоит из набора js классов. Активно используется библиотека JQuery и модули для неё: jquery-autocomplete и SimpleModal. Имеется ядро системы, основная функция которого сводится к хранению и получению пароля, а также шифрованию и расшифровке данных с помощью этого пароля. Все остальные модули системы (используя шаблон observer) уведомляются о получении пароля от пользователя или же об истечении времени его хранения. В зависимости от этого происходит расшифровка закрытых данных с дальнейшим отображением, либо же очистка/шифрование и блокировка.
Все коммуникации между клиентом и сервером осуществляются данными в JSON-формате. При старте веб-приложения все справочные данные уже присутствуют на странице в виде JS массивов и объектов. Дальнейшие запросы выполняются с помощью фоновых AJAX запросов.

Для серверной стороны был разработан микро-фреймворк с поддержкой ЧПУ и абсолютно минимальным функционалом. Подход «ничего лишнего» и максимальное кеширование (общие данные — APC, пользовательские — JSON в gzипованных файлах на RAMFS разделе в оперативной памяти) позволил добиться весьма внушительных показателей быстродействия. Так, к примеру, генерация страницы закрытой пользовательской секции занимает 5-7ms на старой машине уровня Athlon 2800+.

В качестве веб-сервера используется Lighttpd. PHP-FPM как FastCGI процесс-менеджер.
База данных — MySql. Доступ осуществляется с помощью своей реализации подхода, аналогичного библиотеке MeekroDB. Разница заключается в использовании PDO и встроенной валидации таблиц и полей. Данная библиотека выделена в отдельный проект. Использование PDO в теории означает возможность работы с другими базами (помимо MySql), но это не тестировалось.

Для минимизации обращений к сереверу, все JS файлы упакованы в один собирательный файл all.js, а все CSS файлы — в all.css. При модификации любого исходного файла в отладочном режиме происходит автоматическа пересборка.

В системе присутствуют два шелл-скрипта init.sh и halt.sh, выполняемые при старте и выключении сервера соответственно:
  • init.sh создает директорию для кеша (если необходимо) и монтирует ее как RAMFS. Если имеется бекап ранее кешированных данных, то они переносятся в кеш. Дополнительно происходит проверка и создание (если необходимо) вложенных директорий кеша, отвечающих за разные данные. Устанавливаются требуемые права доступа. Генерируется структура базы данных для использования в последующей верификации имен таблиц и полей. Проверка и создание папки логов, её содержимого и установка прав. Подготовка собирательных файлов для JS и CSS файлов. Запуск php-fpm и lighttpd.
  • halt.sh завершает работу lighttpd и php-fpm. Осуществляет бекап всех кешированных данных и отключает кеш.

В заключение


Система бесплатная и открыта для всех. Более того, распространяется с открытыми исходными текстами, так что любой желающий может лично провести аудит кода или, если потребуется, установить эту систему на свой личный домашний или корпоративный сервер. Полные исходные коды находятся в публичном mercurial репозитории, а подробные инструкции по установке — в вики.
В планах: добавить импорт/экспорт данных, детальный аудит, управление сессиями, настройки и многоязычность.
Адрес сайта — http://fortnotes.com/
Или защищённое шифрованное соединение — https://fortnotes.com/
Проект на ohloh.net.
Конструктивные комментарии и пожелания приветствуются.
Приятной и безопасной работы :)

Update (2013.02.10):
Проведена чистка кода и документации, правка мелких багов.
Добавлена возможность запуска с использованием web-сервера Apache.
Добавлена поддержка встроенного PHP web-сервера. Это снимает обязательную зависимость от Apache или Lighttpd.
Добавлена поддержка sqlite баз. Это дает возможность быстрой установки системы вообще без внешних баз данных (типа Mysql).
Созданы представительства в различных соц-сетях: Google+, Facebook, ВКонтакте.

Update (2013.03.30):
Очередная порция мелких правок, оптимизаций и обновлений документации исходного кода.
Активация и поддержка механизма SJCL генерации энтропии для улучшения качества и криптостойкости генерируемых случайных паролей.
Долгожданная реализация восстановления бекапа. Пользователь и пароль в бекапе должны совпадать с логином и паролем аккаунта где производится восстановление. Все старые данные будут удалены, а данные из файла бекапа импортированы.
При экспорте предлагается более удобное имя, появилась возможность полностью выйти из системы в окне запроса пароля.
Добавлено детальное пошаговое руководство по установке проекта (система windows, база Sqlite, встроенный веб сервер php) и подробное описание архитектуры на английском языке.

Update (2013.11.13):
Ведется полная переработка системы. Упор на масштабируемость, поддержку многих платформ, простоту установки и работы. Приглашаются все желающие.
Станислав @DarkPark
карма
5,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (21)

  • 0
    Изобрели велосипед. Есть же www.clipperz.com/
    И как я буду уверенным, что в какой-то момент вы не подмените JS отвечающий за шифрование и не сольете все мои пароли?
    • +4
      тут больший функцинал, причем удобнее
      я не подменю и планирую следить чтобы не взломали и не подменили
      но самое главное — вам и не надо мне доверять — скачайте себе и установите на свой сервак
      там точно не подменят :)
      • 0
        У клипперз, похоже, есть/будет некая возможность делиться паролями с другими участниками.
        Был бы интересен и такой функционал тут.
        • 0
          думал над такой идеей
          еще не отказался, но пока что не вижу способов полноценно расшаривать данные без ущерба для безопасности
          да и все пользователи в системе анонимны — это же не социальная сеть, тут главный упор на надежности
      • 0
        «Планирую следить» — отличная гарантия безопасности.
        Да и собственный сервер тоже ничего не гарантирует.
        • 0
          абсолютных гарантий не существует
          сам я параноик и проект создавал для себя, чтобы быть максимально спокойным за сохранность своих данных
          с другой стороны мы склонны переоценивать свою значимость и важность наших данных
          но все же, если данные действительно важны, то именно этот проект позволит их полностью обезопасить на своих (возможно даже закрытых от инета или в VPN) серверах без ущерба для юзабилити
          не думаю что возможна большая безопасность при разумном подходе
          • 0
            Специализированные приложения обеспечивают бОльшую безопасность без ущерба для юзабилити, например.
            • 0
              в целом да
              но это просто другая ниша
              данный проект — для хранения данных с многопользовательским доступом из разных точек
    • 0
      Запустить свою копию, взяв исходники из репозитория.
      Кстати достаточно слить только username + password, а не подменять всю логику шифрования.
  • 0
    у меня на ФФ11.0 жутко тормозит ввод данных в формы. т.е. символы появляются раз в секунду.
    • 0
      спасибо
      постараюсь это перепроверить
  • +2
    Без сравнения с Lastpass обзор как-то не полон. Опенсорс это гуд, но как уже заметили, гарантировать сохранность js кода никак не получится.
  • 0
    Вроде автор русский а сервис на английском, странно =)
    • 0
      изначально задумывал как интернациональный проект
      начал с инглиша как с самого сложного :)
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      на данный момент у меня есть только самоподписанный сертификах для https
      поэтому защищенное соединение по желанию — кто знает что это такое и зачем, того не отпугнут предупреждения браузера
      я уверен, что, заложенные в проект идеи, в целом удачны, а реализация пусть пока и не идеальна, но тоже хороша, так что очень надеюсь, что проект приживется и со временем обрастет всем необходимым — от мультиязычности до широкой поддержки на мобильных платформах
  • 0
    Меня больше интересует возможность интеграции с вот этой штуковиной.
    standards.freedesktop.org/secret-service/
    Было бы круто уметь синкать бумажники между машинками.
  • 0
    Вы молодец.
    • 0
      спасибо :)
  • 0
    Занимаюсь в данный момент похожим проектом, только для себя, и на клиентской стороне используется исполняемое приложение с поддержкой биометрического контроля, плюс в возможностью подстановки выбранных приватных данных в формы и окна ввода пароля различных приложений. Возник вопрос —
    выходит, все операции по шифрованию/дешифрованию криптоконтейнера осуществляются на локальной машине? Если так, то предоставьте пользователям возможность использовать собственные алгоритмы или библиотеки для шифрования данных. Открытый код. Скажем, я могу не доверять Вашей библиотеке, т.к. не уверен в правильности и надежности алгоритма. Предоставьте возможность мне удостовериться в его корректности, и я буду пользоваться сервисом в полной уверенности, что контейнер зашифрован так, как он зашифрован, и никак иначе.
    • 0
      Открыт весь проект, а не только одни алгоритм шифрования.
      Выбор библиотеки SJCL (Stanford Javascript Crypto Library) не был случайным — я перебрал кучу альтернатив, изучал и проводил тестирования, так вот данная библиотека оказалась лучшей со значительным опережением.
      Вы легко можете лично ее проверить.
      Но если по каким-либо причином ее надежность не покажется достаточной (по очевидным причинам надежность моего сайта тоже скорее всего вас не впечатляет), то после скачивания исходников моего проекта и разворачивания их на своем сервере, вы можете легко заменить алгоритм SJCL на любой другой. Благодаря модульности и тому, что все функции шифрования собраны в двух функциях ядра проекта это не составит ни малейшего труда.
      Удачи :)

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