В этой статье я хочу рассказать, как я придумал идею web-сервиса защищенных социальных сетей. Как её реализовывал и на каких технологиях. Поделюсь технологическими решениями проблем во время разработки сервиса.

image

Идея этого проекта у меня появилась после ознакомления с современным положением дел в области шифрования. Я столкнулся в двумя проблемами.

С одной стороны, это полная незащищенность пользователей от утечек информации из социальных сетей, мессенджеров и тд. Например Skype или Telegram хранит все переписки у себя на серверах и по требованию правительства предоставляют любые данных из этих переписок. Еще вспоминается, недавний взлом сайта знакомств для супружеских измен Эшли Мэдисон, где уплыли данные пользователей.

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

Довольно интересное решение предлагает Bitmessage. Как сказано в википедии «жертвует некоторым удобством ради безопасности и децентрализации» это на мой взгляд ключевой недостаток данного решения.

В интернете я встретил сервис, который позволяет шифровать текстовые заметки и хранить их в облаках. Доступ осуществлялся через обычный браузер и нужно было знать пароль от своих заметок. Фишка была в том, что сам сервис гарантировал, что он не может подсмотреть что у вас в заметках, так как шифрование происходило у вас в браузере по вашему паролю. А на сервере все передается уже в зашифрованном виде. Использовался алгоритм симметричного шифрования. Другими словами если кто-то получит доступ к вашим заметкам, то толку от этого нет, так как они зашифрованы.

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

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

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

Когда встал вопрос о выборе технологий, я долго думал, сделать ли все быстро и на старых проверенных вещах. А может попробовать, то что новое и за чем стоит будущее. В итоге я написал серверную часть на Scala под управлением Play Framework на базе данных Cassandra. Клиентскую часть на CoffeeScript под управлением AngularJS. Дизайн взят от Bootstrap. Шифрование делал при помощи Forge библиотеки на JavaScript. К сожаление в HTML5 нет встроенных механизмов шифрования.

Архитектурно это выглядит как JavaScript-клиент, которых ходит по Rest на сервер. Также используется WebSocket для получения нотификаций о новых сообщений с сервера. Каждое WebSocket-соединение порождает Actor-a, который подписывается на шину событий Akka и если событие связано с его пользователем, то пересылает его в браузер.

Отдельно хочу отметить опыт использования базы данных Cassandra. Это несколько не привычно. Когда работаешь с обычной базой, то накидываешь таблицы, поля и пускаешь по ним любые запросы. Если тормозит, то добавляешь индексы. У Cassandra наоборот. Каждая таблица это по сути один главный запрос который быстро идет по заданным ключам в таблице. Те если вы решили как-то по иному с другими условиями выборки выдрать из нее данные, то вам придется делать еще одну таблицу и другие к ней ключи и по-сути дублировать данные. Этот подход мешает для быстрой разработки, так как тебя заставляет сразу все оптимально продумывать. Зато на продакшен вы тормозную какашку не выкатите:)

С исходными кодами проекта можно ознакомиться тут: github.com/evgenyigumnov/protectednet Я сделал проект Open Source и сам сервис бесплатным.

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


  1. sopov
    19.11.2015 09:40

    И первый вопрос: как вы работаете с файлами?


    1. igumnov
      19.11.2015 10:22

      Передаю в теле сообщения как json поле в формате base64.
      Ну и тело сообщение зашифровано.


      1. sopov
        19.11.2015 10:36

        Понятно, а обратно как? Чтобы скачать файл, его нужно же расшифровать и сохранить на клиенте.


        1. igumnov
          19.11.2015 10:42

          Расшифровывается в браузере при помощи JavaScript. И храниться в оперативной памяти, как кликнешь скачать он из памяти его записывает на винт. Вот тут технические детали stackoverflow.com/questions/3665115/create-a-file-in-memory-for-user-to-download-not-through-server


  1. kahi4
    19.11.2015 10:52

    и к тому же режим секретного чата, только с одним пользователем, группового режима нет

    И как вы побороли эту проблему у себя?

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


    1. igumnov
      19.11.2015 10:59

      и к тому же режим секретного чата, только с одним пользователем, группового режима нет

      И как вы побороли эту проблему у себя?


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

      Надежность системы безопасности равняется надежности самого ненадежного элемента (простите за тавтологию). В данном случае — браузер, особенно с установленными расширениями.

      Если не доверяете своему браузеру — поставьте Tor-браузер.

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

      При регистрации разово генерятся приватный и публичный ключ. И при повторном «входе» публичный ключ остается тем же.


      1. lair
        19.11.2015 11:18

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

        Ну то есть в чате из N собеседников будет генериться в N-1 раз больше сообщений?


        1. igumnov
          19.11.2015 11:19

          В текущей реализации — да. Но я знаю как это обойти. Закожу в следующей версии.


          1. sopov
            19.11.2015 11:27

            С помощью сессионных ключей, верно? )


            1. igumnov
              19.11.2015 11:31

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


              1. lair
                19.11.2015 11:36

                … а где будет храниться эта пара ключей?


                1. igumnov
                  19.11.2015 11:48

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


                  1. vlreshet
                    19.11.2015 13:18

                    Шифровать ключи для шифрования с помощью других ключей для шифрования… это всё будет быстро работать?


                    1. igumnov
                      19.11.2015 13:20

                      Да -)


                  1. VoidEx
                    20.11.2015 01:07

                    его личным приватным ключом

                    Вы имеете в виду симметричный, который известен только пользователю?


                    1. igumnov
                      20.11.2015 06:45

                      симметричным который зашифрован приватным ключом пользователя который зашифрован паролем пользователя


          1. lair
            19.11.2015 11:30

            … и как же?


            1. igumnov
              19.11.2015 11:31

              см выше


  1. rPman
    19.11.2015 11:33

    Пожалуйста, перестаньте повторять одну и ту же ложь, каждый! каждый кто берется за описание технологии секретного месседженера об это спотыкается:

    В интернете я встретил сервис, который позволяет шифровать текстовые заметки и хранить их в облаках. Доступ осуществлялся через обычный браузер и нужно было знать пароль от своих заметок. Фишка была в том, что сам сервис гарантировал, что он не может подсмотреть что у вас в заметках, так как шифрование происходило у вас в браузере по вашему паролю. А на сервере все передается уже в зашифрованном виде. Использовался алгоритм симметричного шифрования. Другими словами если кто-то получит доступ к вашим заметкам, то толку от этого нет, так как они зашифрованы.
    Это взаимоисключающие понятия! Если приложение может автоматически обновляться, под контролем сервера, то ни о какой защищенности и гарантиях говорить нельзя!

    Только standalone приложение, opensource и собранное и установленное вами (или тем кому вы доверяете) может что то гарантировать (точнее будет гарантировать тот кто собрал установил и/или провел аудит).


    1. igumnov
      19.11.2015 11:38

      Да все верно. Но кто вам дает гарантию что вы собрав свою стенд элон апликуху используя сторонние либы шифрования которые вы не контролируете не получите в итоге формально все зашифровано а в алгоритме шифрование умышленно снизили безопасноть? В итоге все сводиться к тому что вам приходиться доверять разработчикам сторонних библиотек. А они в свою очередь не заинтересованы такое безобразие делать так как на кону стоит репутация. С онлайн сервисами тоже самое, все держится на доверии и репутации.


      1. kahi4
        19.11.2015 11:46

        Офтопик: думал, у вас сломалась запятая, но нет — одну вы поставили, правда там, как раз, должно быть либо двоеточие, либо тире...

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


        1. igumnov
          19.11.2015 12:05

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


          1. lair
            19.11.2015 12:08

            Вообще глобальный тренд идет не ставить приложения вообще, а пользователя веб-сервисами.

            Ага, особенно на мобильных устройствах. Спасибо, но нет.

            Это удобно

            Вот только «удобно» и «безопасно» почти всегда противоречат друг другу.


            1. igumnov
              19.11.2015 12:17

              Вообще глобальный тренд идет не ставить приложения вообще, а пользователя веб-сервисами.

              Ага, особенно на мобильных устройствах. Спасибо, но нет.


              Ну на мобильных устройствах — согласен удобнее приложения — у меня апи открыт (см исх код-)))) — можно и приложуху написать как клиент к системе. По сути у меня в браузере запускается приложение на JavaScript.


        1. GamePad64
          19.11.2015 22:12

          Есть такая идея: в интерфейсе веб-приложения предложить юзеру скачать опенсорсное расширение для браузера, которое сможет сравнивать контент с сайта с некоторым эталонным образцом. А образец — на гитхаб положить.
          Ограничение: веб-приложение должно быть одностраничным.
          Также, можно предусмотреть возможность «закрепить» определённую версию у пользователя.

          По сути, это превратит сайт в некое «приложение», которое будет находиться на компьютере пользователя, и можно будет «закрепить» определённую версию, для которой можно будет провести аудит.


          1. igumnov
            20.11.2015 07:55

            Тоже вариант


          1. rPman
            20.11.2015 11:52

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


  1. lair
    19.11.2015 11:33

    1. Что в вашем решении несет функциональность социальной сети? В описании есть только мессенджер
    2. Какие пользовательские данные хранятся на сервере?
    3. Что мешает серверу отслеживать, кто с кем переписывается?
    4. От каких атак защищает ваша система?
    5. Что конкретно вы выиграли от использования кассандры?


    1. igumnov
      19.11.2015 11:44

      Что в вашем решении несет функциональность социальной сети? В описании есть только мессенджер

      Есть посты глобальные на всю сеть и есть личные сообщения между пользователями.
      Какие пользовательские данные хранятся на сервере?

      имя логина, публичный и приватный ключ(закрыт паролем)
      Что мешает серверу отслеживать, кто с кем переписывается?

      как раз не мешает, в базе в отрытом виде лежит кто кому и когда пишет, а вот ЧТО пишет — зашифровано
      От каких атак защищает ваша система?

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

      хайлоад в коробке


      1. lair
        19.11.2015 11:51

        Есть посты глобальные на всю сеть

        Где они хранятся?

        как раз не мешает, в базе в отрытом виде лежит кто кому и когда пишет

        Вы осознаете, что это фундаментальное нарушение конфиденциальности, и ни о какой защищенности после этого говорить нельзя?

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

        Вообще-то, по вашему же утверждению, тела сообщений и файлы не хранятся на сервере, поэтому эта атака не применима.

        хайлоад в коробке

        Это бессмысленная фраза. Что конкретно? Увеличение производительности? По сравнению с чем? На каких сценариях использования?

        Извините, но для того, что вы храните — по вашему утверждению — на сервере, достаточно KV-хранилища.


        1. igumnov
          19.11.2015 11:58

          Есть посты глобальные на всю сеть

          Где они хранятся?

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

          как раз не мешает, в базе в отрытом виде лежит кто кому и когда пишет

          Вы осознаете, что это фундаментальное нарушение конфиденциальности, и ни о какой защищенности после этого говорить нельзя?

          это зависит от того — можете ли вы сопоставить кому какой логин принадлежит

          Вообще-то, по вашему же утверждению, тела сообщений и файлы не хранятся на сервере, поэтому эта атака не применима.

          я утверждал что храню но в зашифрованном виде

          Это бессмысленная фраза. Что конкретно? Увеличение производительности? По сравнению с чем? На каких сценариях использования?

          Извините, но для того, что вы храните — по вашему утверждению — на сервере, достаточно KV-хранилища.


          а реплицировать на кластер эти KV кто будет? или мне еще логику репликации писать? и тд и тп


          1. lair
            19.11.2015 12:06

            на сервере

            В открытом виде?

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

            Угу. Одна маленькая закрытая сеть. А если я вхожу в маленькую закрытую сеть своего ВУЗа и маленькую закрытую сеть своей компании, и хочу написать пост, который виден и там, и там — что мне делать?

            это зависит от того — можете ли вы сопоставить кому какой логин принадлежит

            Во-первых, даже если не могу, конфиденциальность уже нарушена. А во-вторых, чаще всего — могу. Например, если это логин моего друга и другого моего друга, с которым я перестал общаться.

            я утверждал что храню но в зашифрованном виде

            Угу, цитирую: «имя логина, публичный и приватный ключ(закрыт паролем)».

            Ну ок, вы храните еще и историю переписки. Что хранится в открытом виде, а что в зашифрованном?

            Вообще, более общий вопрос: какая информация о переписке проходит через сервер в открытом виде, а какая — в закрытом?

            а реплицировать на кластер эти KV кто будет?

            Движок, очевидно. В том же редисе кластер из коробки.


            1. igumnov
              19.11.2015 12:14

              на сервере

              В открытом виде?

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



              Угу. Одна маленькая закрытая сеть. А если я вхожу в маленькую закрытую сеть своего ВУЗа и маленькую закрытую сеть своей компании, и хочу написать пост, который виден и там, и там — что мне делать?

              я делал продукт для изолированных команд — которым нужна повышенная защищенность — то что вы описываете это публичные сети
              и кросс постинг -)

              я утверждал что храню но в зашифрованном виде

              Угу, цитирую: «имя логина, публичный и приватный ключ(закрыт паролем)».

              Ну ок, вы храните еще и историю переписки. Что хранится в открытом виде, а что в зашифрованном?

              Вообще, более общий вопрос: какая информация о переписке проходит через сервер в открытом виде, а какая — в закрытом?


              в закрытом виде только сами сообщения и файлы ну и приватный ключ — все остальное и храниться и проходит через сервер в открытом виде — и ну да пароль на сервер не передается

              а реплицировать на кластер эти KV кто будет?
              Движок, очевидно. В том же редисе кластер из коробки.

              ну если так абстрагироваться — то да и редис подойдет


              1. lair
                19.11.2015 12:25

                закрытом

                Зашифрованном каким ключом?

                я делал продукт для изолированных команд — которым нужна повышенная защищенность

                Тогда это не социальная сеть.

                в закрытом виде только сами сообщения

                Что значит «сами вообщения»? Только тело?

                ну если так абстрагироваться — то да и редис подойдет

                Вот поэтому я и спрашиваю: что вы выиграли от применения кассандры.


                1. igumnov
                  19.11.2015 12:36

                  Да только тело шифровано ну и файлы тоже, так как они внутри тела сообщения или поста.


                  1. lair
                    19.11.2015 12:39

                    Значит, ваша «защищенная» система позволяет раскрыть не только кто с кем переписывался, но еще и как минимум когда (это если вы геолокацию делать не будете).

                    Извините, на «повышенную защищенность» никак не тянет. Собственно, любая система, в которой сообщения идут через сервер, этому подвержена.


                    1. sopov
                      19.11.2015 12:52

                      И что вам даст: login1 и login2 общались вчера в 21:21?


                      1. lair
                        19.11.2015 12:56

                        login1 — это мой сотрудник
                        login2 — журналист
                        login3 — трейдер

                        в 21:30 вышла статья, по результатам которой в 21:45 посыпались акции моей компании на бирже.


                        1. sopov
                          19.11.2015 12:59

                          И как выяснить кто виноват?


                          1. lair
                            19.11.2015 13:00

                            Прийти к сотруднику и вежливо поговорить.


                            1. sopov
                              19.11.2015 13:07

                              Это вы знаете кому какой логин принадлежит, а владелец сервиса нет и дяди в сером, тоже не всегда будут знать кому какой логин принадлежит. А если даже и узнают, то данные-то зашифрованы…
                              Конечно крипторектальный метод всегда может если нужен пароль )))


                              1. lair
                                19.11.2015 13:17

                                Что знают трое — знает и собака. Чем меньше информации об обмене утекает, тем лучше.


                    1. igumnov
                      19.11.2015 13:01

                      Я бы сказал что уровни защищенности разные существуют. Моя была цель что бы именно содержимое сообщений расшифровать нельзя. И что бы атака посредника была отражена. Далее если уж так боитесь идентификации. Так воспользуйтесь Tor-браузером и через него зарегайте в этой сети акаунт.

                      Если хочется вообще без логинов и времени сообщений то лучше использовать Bitmessage. Но вы получите массу неудобств его использования.


                      1. lair
                        19.11.2015 13:02

                        Далее если уж так боитесь идентификации. Так воспользуйтесь Tor-браузером и через него зарегайте в этой сети акаунт.

                        Это ничего не изменит.

                        Если хочется вообще без логинов и времени сообщений то лучше использовать Bitmessage. Но вы получите массу неудобств его использования.

                        Так что мешает сделать альтернативу, в которой нет этих неудобств?


                        1. sopov
                          19.11.2015 13:03

                          Так что мешает сделать альтернативу, в которой нет этих неудобств?

                          Сделайте!


                          1. lair
                            19.11.2015 13:05

                            А меня и существующие неудобства не раздражают. Я просто не вижу смысла в системе, которая прикидывается защищенной, но при этом протекает.


                            1. igumnov
                              19.11.2015 13:12

                              Протикает это ты когда длину ключа поставил маленькую… Кстати PGP в емайлах те же самые проблемы имеют. Только никто их за это не ругает.


                              1. lair
                                19.11.2015 13:18

                                От длины ключа утечка информации, которую вы храните в открытом виде, никак не зависит.


                                1. igumnov
                                  19.11.2015 14:01

                                  Сложно спорить когда у оппонент другие критерии.


  1. igumnov
    19.11.2015 11:57

    удалено сообщение


  1. Revertis
    19.11.2015 14:15

    Telegram хранит все переписки у себя на серверах и по требованию правительства предоставляют любые данных из этих переписок
    А откуда такая инфа? Или вам дали задание тоже поговнить на Телеграм сейчас?


  1. sopov
    19.11.2015 14:22

    tlgrm.ru/privacy

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

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


    1. Revertis
      19.11.2015 14:59

      Я подозреваю, что вы пытались мне ответить? Но где ответ на «и по требованию правительства предоставляют»?


      1. sopov
        19.11.2015 15:12

        Они этого не напишут, но по решению суда все отдадут.


        1. Revertis
          19.11.2015 15:17

          Суд какой юрисдикции, интересно?


          1. sopov
            19.11.2015 15:26

            Той, где находятся сервера и ключи…


  1. ystr
    19.11.2015 15:04

    К сожаление в HTML5 нет встроенных механизмов шифрования

    В общем-то есть, хотя и в статусе «W3C Candidate Recommendation». Как вариант замены Forge могу предложить библиотеку написанную мной — PKIjs.

    А насчет построенной схемы обмена сообщениями: схема впринципе рабочая, однако возможны мелкие проблемы. Так, например Forge для PKCS#12 (да и для шифрования PKCS#8 ключей) использует устаревшие схемы генерации ключа на основе пароля. Сразу скажу, что пока в PKIjs отсутствует поддержка PKCS#12 и поддержка зашифрованных приватных ключей.


  1. mwizard
    19.11.2015 18:09

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

    Ознакомьтесь, пожалуйста, с основами криптографических алгоритмов, перед тем, как придумывать свои «защищенные» сети — вы серьезно подводите людей, которые поверят вам. А вот случайно или намеренно…


    1. igumnov
      20.11.2015 06:48

      я не спорю что это в идеальном случае надо так делать — но всегда есть компромис — закрыть свой приватный ключ паролем хоршим — безусловно это снижает уровень безопасности — но не драматично