Привет, %username%!
Этот пост стоило написать года три назад, когда появилась идея опенсорсного защищенного P2P мессенджера. Но я все это время надеялся, что хватит сил запилить проект в одного. К сожалению, время шло, а проект так и не ожил. Единственное, что я успел сделать — разработать детальную концепцию, подобие протокола и накодить всяких криптоштук, которые пригодились бы при написании этого мессенджера. А теперь, когда на сцене есть bitmessage, очень похожий на мою идею BitTorrent Chat и ненавистный всем Telegram, вижу, что поезд ушел и я при всем желании на него не успею.
Поэтому вашему вниманию предлагается концепция защищенного, анонимного P2P мессенджера с околонулевым порогом вхождения. Я ему даже название придумал:
Итак, это пост о том, каким бы мог стать ParanoIM, если бы я довел его до ума.
Судя по тому, что выложили о своем проекте товарищи их BitTorrent Chat, некоторые моменты у меня с ними очень похожи. С них и начнем.
1. DHT
Без этой штуки никуда. Если вы не в курсе, что это такое, Kademlia для вас — это пустой звук, то стоит почитать об этом в соответствующих статьях. Здесь я лишь расскажу кто является нодами и что лежит в самой таблице.
Нода
Физический узел. Каждая нода при запуске генерирует новую ключевую пару ECC, её идентификатором будет являться хэш открытого ключа. При обмене информацией с другими нодами происходит обмен открытыми ключами, таким образом появляется возможность установить защищенное соединение между нодами. Конечно, тут возможна атака MITM, но нам это не сильно страшно, потому что ноды сами по себе не обмениваются какой либо ценной незашифрованной информацией друг с другом во время построения сети.
Абонент
Или просто пользователь мессенджера. Человек, который генерирует себе перманентную ключевую пару ECC, хэш от публичного ключа которой будет его уникальным постоянным адресом. Этот хэш он всем раздает, публикует и всячески распространяет. Конечно, не очень удобно диктовать бабуле 512битный хэш, но тут ничего не поделать. Есть способ обойти это неудобство, но об этом позже.
Изначально абонент ведет себя как обычная нода. Обменивается ключами, пополняет список соседей, ничего необычного. Но, для того, чтобы начать общаться, он случайным образом выбирает несколько нод и формирует из них туннель следующим образом:
- Выбирает еще несколько proxy нод (или не выбирает), которые будут отдавать команды этим нодам
- Каждой из выбранных нод сам или через прокси ноды посылает команду «Принимай сообщение для Id такого то и передавай ноде такой то»
Логично, что последней нодой «такой то» будет нода самого абонента, но остальные об этом знать не будут. Всё, что известно остальным нодам — это то, что зашифрованное сообщение для абонента X надо передать ноде Y. А уж чего она с ним там дальше будет делать, это нам не ведомо. Может дальше передаст, а может сама расшифрует.
После того, как все выбранные ноды ответили согласием, абонент публикует в DHT (так же, через цепочку прокси нод, или напрямую) подписанную своим закрытым ключом пару «Id абонента — Id ноды, принимающей для него сообщения». Принимающих нод может быть несколько, для большей отказоустойчивости.
После этого абоненту можно посылать сообщения, зашифровав их общим с ним ключом (ECDH) и поверх этого зашифровав сообщение общим с принимающей нодой ключом. Принимающая нода расшифровывает свою часть сообщения и передает его дальше к абоненту, зашифровывая общим со следующей нодой ключом.
Когда сообщение попадает к ноде абонента, он его никуда не пересылает, а расшифровывает и собсно читает. (похоже на i2p)
То же самое работает и в обратную сторону. Отправляющая сторона может указать в сообщении список нод, которые будет принимать ответы. Либо этот список абонент может сам получить, сделав запрос в DHT.
Как видите, тут исключена возможность MITM между абонентами, т.к. они изначально знают именно открытые ключи друг друга, а не какие то другие идентификаторы. Всё, что может сделать атакующий — попытаться раскрыть анонимность, но при большом количестве нод ему будет это очень сложно сделать.
2. Offline сообщения
Тут всё просто, их можно хранить в BitMessage-подобном хранилище, оно идеально для этого подойдет.
3. А где же нулевой порог вхождения?
Проблема всяких крутых штук вроде тора, i2p, bitMessage и других в том, что их нужно долго конфигурить, у них корявый интерфейс и они очень сложные для неподготовленных пользователей.
Моей идеей было сделать jabber сервер, к которому локально цеплялся бы абонент любым jabber клиентом, к которому он привык, и который сам был бы клиентом для сети ParanoIM. Генерацию ключевых пар\адресов можно было бы сделать в простом web интерфайсе, который бы запускался локально.
4. Что с длинными адресами?
Это была самая вкусная часть, в том плане, что она должна была приносить деньги. Предполагалось, что в клиент будет зашит публичный ключ разработчиков. Конечно, это опен сорс и кто хочет мог его подменить, но основная часть пользователей все равно бы пользовалась официальным клиентом.
Так вот, можно было бы продавать обычные человекочитаемые имена/уины, привязывая их к хэшам публичных ключей абонентов. А потом списки этих пар подписывать закрытым ключом и рассылать всем нодам апдейтом. Что, конечно, не мешало бы обращаться к этим абонентам по их обычному хэшу.
Но, можно было бы обойтись и более цивильной вещью вроде NameCoin. Тогда бы вообще отпала необходимость в какой либо централизации.
Вот собсно и всё, таким я хотел бы видеть свой утопичный IM, и надеюсь, BitTorrent Chat будет очень на него похож.