
Короткое напоминание
Месяц назад я тут рассказывал, как сделал свой сервис для обмена чувствительной и приватной информацией Copy Sync — устроенный так, чтобы мой сервер физически не мог прочитать ваши пароли и ссылки. Текст шифруется прямо на вашем устройстве, на сервер уезжает уже зашифрованная каша, ключа от неё у меня нет.
Многие тогда справедливо спросили в комментах: «а ключи-то от шифрования откуда устройства берут?» Вопрос в точку. И в той статье я сам честно написал, что тут осталась слабое место. Вот её и чиню.
В чём была дыра
Объясню простым языком:
Чтобы зашифровать сообщение для вашего второго устройства, первому нужен «публичный ключ» второго, что-то вроде открытого почтового ящика, куда можно бросить письмо, но достать его может только владелец. Вопрос: откуда первое устройство этот ящик берёт? Спрашивает у сервера. У моего сервера.
И вот тут собака зарыта. А что если сервер (или тот, кто его взломал) вместо настоящего ящика вашего устройства подсунет свой? Тогда:
-
ваше первое устройство шифрует письмо в подставной ящик;
-
сервер его спокойно открывает, читает, потом перепаковывает в настоящий ящик и отправляет дальше;
-
второе устройство получает письмо как ни в чём не бывало.
Оба ваших устройства довольны, а посередине кто-то всё прочитал. Это называется «человек посередине» (man-in-the-middle). И самое обидное шифрование тут ни при чём, оно идеальное. Просто зашифровали не туда. А «не туда» подсунул именно тот, кому мы вроде как не должны были доверять, мой сервер.
Неприятно, что мой же сервис, про который я писал «нечем вас прочитать», в этом сценарии всё-таки мог. Так не пойдёт.
Как защититься
Способ старый и проверенный, такой же используют в Signal и WhatsApp, когда показывают «код безопасности». Идея простая:
У каждого ящика-ключа есть короткий отпечаток — набор букв и цифр, который из этого ключа однозначно вычисляется. Как отпечаток пальца: у разных ключей он разный, у одного и того же — всегда одинаковый.
Вы открываете Copy Sync на двух своих устройствах и сравниваете отпечатки глазами. Совпали — значит, между устройствами реально один и тот же ключ, никто посередине не встрял. А если сервер подсунул свой ключ — отпечаток сразу разойдётся, и вы это увидите. Подделать его нельзя: отпечаток намертво привязан к ключу.
Пять секунд работы — и MITM из «незаметно читает всё» превращается в «попадётся на первой же сверке».
А теперь — самое главное, ради чего и пишу
Когда вы сверили отпечатки и нажали «Сверено», эту галочку надо где-то запомнить. И вот тут у меня был соблазн сделать «как удобно»: сохранить её на сервере, чтобы синхронизировалась между устройствами.
Я этого не сделал. Сознательно.
Смотрите. Мы защищаемся от кого? От сервера. А теперь представьте, что я бы доверил тому же серверу хранить отметку «этому ключу можно верить». Взломщик просто поставил бы галочку «проверено» своему поддельному ключу и вся защита превратилась бы в спектакль. Нельзя ставить сторожить дверь того, от кого ты эту дверь запираешь.
Поэтому галочка «сверено» живёт только в вашем браузере и на сервер не уходит вообще никогда. У этого есть приятный побочный эффект: галочка привязана к самому ключу. Если сервер завтра попробует подменить ключ, отметка «проверено» слетит сама собой, и устройство снова покажет «не сверено». Вы заметите, что что-то поменялось. Подмена ключа автоматически сбрасывает доверие — это не баг, это и есть защита.
Цена честная: сверять придётся на каждом устройстве отдельно. Но это в сто раз лучше, чем доверять «проверку» тому, кого проверяешь.
Бонусом — подключение второго устройства по QR
Заодно сделал удобную мелочь. Раньше, чтобы добавить второе устройство, надо было вводить пароль. Теперь на первом устройстве показывается QR-код, вы сканируете его вторым и всё, вы в системе. Без пароля.
И тут важная деталь в том же духе: по QR передаётся только разовый «пропуск» (живёт 5 минут, срабатывает один раз). Ключи шифрования по нему не передаются — второе устройство создаёт свои собственные, прямо у себя, и они его никогда не покидают. Так что даже перехваченный QR не даст доступа к вашим данным.
Честно о том, чего ещё нет
Как и в прошлый раз — про минусы сам, без прикрас:
-
Сверка ручная. Она работает, только если вы реально сравнили отпечатки. Не сравнили — защита не сработает. Я не заставляю это делать насильно, но честно: это инструмент, а не автоматический щит.
-
Сервис пока не предупреждает сам, если ключ вдруг сменился — он лишь снимает галочку «проверено». Автоматическое уведомление «эй, ключ поменялся!» следующая задача.
-
Это по-прежнему пет-проект одного человека. Веб-версия работает, расширение и мобильные приложения — в планах. Код по-прежнему весь открыт — можете сами проверить, а не верить на слово.
Посмотреть
-
Сайт: copysync.ru (заведите два устройства, подключите второе по QR и сверьте отпечатки — увидите всё своими глазами)
-
Исходники: gitlab.com/razgiva/copy-sync
Буду рад вопросам и критике — особенно от тех, кто шарит в безопасности. Нашли, как обойти сверку, — для меня это ценнее лайка.
А вопрос к вам такой: вы вообще когда-нибудь сверяли «код безопасности» в Signal или WhatsApp? Или это та штука, которую все видели, но никто ни разу не нажимал?
ссылка на оригинал статьи https://habr.com/ru/articles/1049780/