Предисловие
Я работаю фронтендером и давненько посматриваю в сторону разработки собственного проекта. Чтобы под капотом были микросервисы, асинхронность, само собой работа с базой данных, в общем все по-взрослому)) Есть идеи, даже выбраны технологии, осталось дело за малым: написать и запустить. И если первое интересно и познавательно, то вот со вторым как-то утомительно: постоянно нужно где-то хранить набор команд для запуска написанных серверов: всякие там ключи, токены, пароли. По мере написания проекта набор этих команд расширяется и превращается в кучу из которой порой не с первого раза вспомнишь, что нужно выполнять в консоли и в какой последовательности. Периодически токены и пароли нужно обновлять и разделять для разных сред выполнения (dev и prod), а еще было бы хорошо не хранить эти данные в открытом виде. Конечно, можно хранить все эти данные внутри приложения, где-нибудь в отдельной таблице или файле, пусть и в не зашифрованном виде. Но что будет, если я начну писать новый проект? Придется отвлекаться заново на решение этой задачи, а хочется сосредоточиться на реализации бизнес логики. Вот для решения этой задачи я и написал сервис о котором пойдет дальше речь.
Как это все устроено?
Предлагаю сначала разобраться с чем работает сервис и затем, что он умеет делать.
Если по-простому, то у нас есть документ который состоит из вкладок, а содержимое вкладок состоит из групп переменных и блоков текста. Всего может быть в неограниченном количестве.
Зачем нужны вкладки?
По вкладкам Вы можете группировать информацию, как посчитаете нужным. Например, у меня разделены по вкладкам данные для запуска на dev и prod среде. Минимально должна существовать хотя бы 1 вкладка.
Зачем нужны группы переменных?
В группах переменных вы можете задавать префикс группы, задавать тип переменных, а также добавлять сами переменные. Существуют несколько типов переменных: обычная строка, несколько типов случайных строк по уровню сложности и кастомная настройка случайной строки. Минимально во вкладке существует хотя бы 1 группа переменных. При этом не обязательно наличие переменных в самой группе. Группы можно импортировать из других вкладок.
Зачем нужны блоки текстов?
В самих блоках собственно хранятся сами конфиги и скрипты, которые включаются в себя имена переменных, которые можно менять в 1 месте но в пределах одной вкладки. Также предусмотрена генерация случайных строк.
Как это все работает?
Давайте представим что у нас есть некие абстрактные команды для запуска серверов
./service_captcha -port=4002 -api_key=xxbbsdas5235
./service_auth -port=4003 -api_key=xxbbsdas5235 -db_login=user -password=12315
Создадим группу переменных и назовем ее API ключи
, проставим ей тип простых случайных строк и добавим префикс api_
Добавим в созданную группу переменную с именем key
, случайная строка сгенерируется автоматически.
Создадим еще одну группу переменных и назовем ее DB
, пусть у нее будет тип простая строка и префикс db_
Добавим в созданную группу переменные login
со значением user
и password
со значением 12315
.
Добавим текст следующего содержания
./service_captcha -port=4002 -api_key=${api_key}
./service_auth -port=4003 -api_key=${api_key} -db_login=${db_login} -password=${db_password}
И мы увидим что вместо имен переменных появились их значения. А если мы нажмем на иконку релоада рядом со значением api-ключа, то увидим, как значение начнет меняться.
Здорово! Теперь осталось сохранить полученный результат.
Как хранятся данные?
Данные хранятся только в зашифрованном виде. Причем первичное шифрование происходит в обязательном порядке в браузере через window.crypto
. Вторичное шифрование необязательно, но оно может усложнить злоумышленнику задачу взлома в случае, если Ваш файл окажется в нехороших руках.
Сначала нужно разобраться как устроено первичное шифрование. Перед сохранением файла у Вас будет запрошен в обязательном порядке приватный пароль. Этот пароль никуда не передается, а шифрует данные, которые вы хотите сохранить.
Чуть подробнее о первичном шифровании
На самом деле на основе Вашего пароля генерируется ключ согласно стандарту PBKDF2, которым шифруются Ваши данные в AES-256. Так что в принципе первичное шифрование достаточно безопасно, если, конечно, Вы не используете пароль что-то вроде "123".
При вторичном шифровании происходит несколько шагов:
задается публичный пароль
зашифрованные на первом этапе шифрования данные передаются на сервер вместе с хешом публичного пароля
на сервере хеш публичного пароля смешивается с солью, доступ к которой обладает сервер, полученным ключом шифруются данные и приписывается id соли
данные отдаются клиенту
Также файл можно привязать к ip адресу.
Как расшифровать данные?
Если у вас на документе не установлен публичный пароль и нет привязки к ip адресу, то расшифровка происходит в самом браузере без передачи данных на сервер. Только нужно ввести правильный приватный пароль.
Если же было применено вторичное шифрование то алгоритм следующий:
пользователю необходимо пройти капчу
если установлен публичный пароль необходимо его ввести
также необходимо ввести приватный пароль
если есть привязка к ip, сервер это учтет, и в случае его несовпадения выдаст ошибку
в случае указания правильного публичного пароля и правильного ip-адреса, если есть указание о привязке, браузеру отдается зашифрованный на 1 этапе документ, который окончательно расшифровывается опять же локально без передачи данных на сервер
Таким образом, сервис никуда не передает данные в открытом виде. В этом можно легко убедиться, посмотреть на "сеть" в инспекторе в Chrome.
Какое шифрование выбирать в итоге?
Если рассмотреть случай, что мы используем простой пароль то в случае первичного шифрования подобрать пароль путем перебора будет значительно легче, чем со вторичным шифрованием. Поэтому, наверное, предпочтительнее будет в данном случае выбрать вторичное шифрование. Если же Ваш пароль достаточно сложный, то можно обойтись и первичным шифрованием.
Послесловие
Вот и окончился ознакомительный рассказ о том, что я писал где-то месяц в свободное от основной работы время. Наверное у сервиса очень простой интерфейс, нет новомодных фишек, но я его делал исходя из моего личного понимания удобства. Например, в первоначальной версии не было переменных, потом мне пришло на ум, что было бы здорово их иметь. Потом пришла идея группировки. Генерация случайных строк была с самого начала, однако их динамическое обновление в процессе нажатия на иконку появилось в последние дни работы над проектом. В целом, думаю, что-то получилось и этим уже даже можно пользоваться, и если этот проект кому-то поможет и окажется востребованным, будет вообще здорово. Как-то так. Спасибо за уделенное время.
PS
Кстати, как думаете можно ли сделать опциональное хранение зашифрованного документа в браузере (localStorage)? Или это не очень секьюрно?