Русский
Русский
English
Статистика
Реклама

Протокол

Схема Шнорра и её роль в Биткоине

21.12.2020 22:14:07 | Автор: admin

Содержание

  • Историческая справка

  • Суть протокола Шнорра

  • Схема подписи Шнорра

  • Почему подписи Шнорра считаются лучше ECDSA?

Комментарий от автора

Данная статья рассчитана на людей, уже знакомых с основами защиты информации. Если слова "Протокол доказательства знания", "Криптосистема с открытым ключом" не являются для Вас заклинаниями, you're welcome!

Историческая справка

Схема Шнорра была изобретена в 1980 гг. Клаусом-Петером Шнорром. Клаус Шнорр - немецкий криптограф, академик, на тот момент профессор и исследователь Франкфуртского университета. Перед публикациейсамой схемы Клаус Шнорр заморочился с патентами, из-за чего вплоть до 2008 года прямое её использование было затруднительно.

В 2008 году, в том же году, когда Сатоши Накамото представил миру Биткойн, срок действия патента Клауса Шнорра истёк. Даже несмотря на то что подписи Шнорра уже можно было использовать, Сатоши Накамото выбрал для Биткоина ECDSA. Это связано с тем, что схема Шнорра ещё не являлась стандартизированной и широко используемой.

Хоть криптографы зачастую и считают ECDSA неудачным, он до сих пор используется. К слову, DSA, предшественник ECDSA, представлял собой гибрид схем Эль-Гамаля и Шнорра, созданный исключительно для обхода патентов Клауса Шнорра Национальным институтом стандартов и технологий США (NIST). После его появления в рассылке Coderpunks начался, что называется, интеллигентный срач, а Клаус Шнорр стал ещё активнее защищать свои патенты.

Суть протокола Шнорра

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

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

Первым делом Алиса выбирает случайное число k из подгруппы порядка q, оно должно быть уникально для каждой сессии. Затем Алиса считает I и посылает его Бобу.

Боб также выбирает случайное число из подгруппы и отправляет его обратно Алисе.

Алиса вычисляет s и отправляет его Бобу.

Боб совершает проверку и подтверждает.

A: ~ k \leftarrow \mathbb{Z}_q, I = g \cdot k\\ B: ~ r \leftarrow \mathbb{Z}_q\\ A: ~ s \equiv r \cdot x + k ~ (\text{mod} ~ q)\\ B: ~ g^s \cdot h^{-r} == I

Схема подписи

Эта схема является по сути развитием интерактивного протокола за исключением того, что r - не случайная величина, здесь берётся вывод случайного оракла.

\text{Задана группа} ~ (G, q, g) \\ \text{Gen}(1^n) = x \leftarrow \mathbb{Z}_q; ~ h = g^x; ~ sk = x; ~ pk = h ~~~ (выводим ~ (sk, pk)) \\ \text{Sign}_x(m) = k \leftarrow \mathbb{Z}_q; ~ I = g^k; ~ r \equiv H(I|m); ~ s = r \cdot x + k ~ (выводим ~ (r, s)) \\ \text{Verify}\left( h, m, (r, s) \right) = I \equiv g^s \cdot h^{-r}, ~ H(I|M) == r \\ sk - секретный ~ ключ, ~ pk - публичный ~ ключ

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

Вычисление значения r таким образом (изначальная схема подписи): r \equiv H \left( I | m \right) называется слабым преобразованием Фиата-Шамира, оно НЕ является безопасным. На практике же стоит также добавлять в r ещё и публичный ключ pk. Слабым преобразованием Фиата-Шамира пользовались до 2010-х годов, хотя оно встречается и сейчас, в нём были найдены различные уязвимости, в частности, например, в системе электронного голосования Helios.

Тут public key (pk) - это элемент группы, т.е. его размер невелик и порядка n (на практике всего 33 байта). Отсюда следует, что размер подписи это также 2 числа из группы, т.е. 2n бит (64 байта на практике). Т.е. в сравнении с предыдущими алгоритмами этот на порядки эффективнее.

Схема подписи Шнорра позволяет подписать очень много документов (учитывая, разумеется, уникальность k). В истории были случаи, когда k совпадали в различных документах и это позволяло вскрыть ключ. Таким образом однажды уже взламывали и перепрошивали приставки, в истории Биткоина тоже были подобные случаи.

Почему подписи Шнорра считаются лучше ECDSA?

Чтобы ответить на этот вопрос давайте рассмотрим три основных критерия, по которым мы сравним ECDSA и подписи Шнорра.

  • Безопасность

  • Размер подписи

  • Приватность

Безопасность ECDSA

Вообще говоря, для ECDSA отсутствуют доказательства безопасности для задачи дискретного логарифмирования в группе точек эллиптической кривой при использовании случайного генератора группы, но на самом деле это не основная причина, по которой многие хотят изменить ECDSA на подписи Шнорра. С 2009 года ECDSA на кривой x3+7 достаточно надёжно работает, и если и была обнаружена какая-то критическая уязвимость, то уже давно об этом знали. То есть фактически на данный момент ECDSA и описанной кривой вполне достаточно. Выходит, дело тут немножко в другом.

Давайте рассмотрим размер подписи. Где вообще на находится это значение? У нас есть транзакция:

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

В выходах находится value и scriptPubKey - условия траты монет, то есть по сути условия, которые должны выполняться для того, чтобы монеты были потрачены.

Если транзакцию подписывает один участник, то размер одиночного значения подписи плюс-минус одинаковый для ECDSA и для подписи Шнорра. Но что если мы используем мультиподпись, т.е. транзакцию подписывает несколько человек?

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

Приватность ECDSA

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

Размер подписи ECDSA

Давайте выделим ключевые поля транзакции: это scriptSig , то есть доказательства владения монетами, и scriptPubKey, то есть условия траты монет. Эти поля занимают самое большое место в входах и выходах транзакций. Изначально архитектура подразумевала, что каждый конкретный вход должен содержать значения подписи (то есть когда вы хотите потратить монет с конкретного выхода, вы должны подать на вход значение подписи). В выходе транзакций находится собственно адрес получателя. То есть как мы уже рассматривали в ECDSA, могла произойти такая ситуация, что в одном входе содержалось n значений, в другом m и т.д. Это огромные объёмы данных.

А что же подпись Шнорра?

Подпись Шнорра позволяет агрегировать значение ключей и подписи. Что такое агрегация? Пусть у нас есть 4 субъекта и есть алгоритм мультиподписи, в случае ECDSA каждый из них создает свою подпись, и на выходе получаем 4 подписи. В случае Шнорра у нас есть все те же четыре субъекта они подписывают транзакцию, значения подписи складывается и мы получаем одно общее значение, которое по размеру равно обычному значению подписи.

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

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

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

Касательно приватности в подписи Шнорра. Что такое общий открытый ключ? В общем виде это сумма публичных ключей, это наш агрегированный публичный ключ. Значение подписи тоже агрегируется таким же образом, и получаем одно общее значение подписи. Этот публичный ключ соответствует этой подписи. Когда валидатор проверяет такую транзакцию, в выходе транзакции у нас находится ровно один публичный ключ, во входе транзакции находится ровно одно значение подписи. То есть независимо от того, подписал транзакцию один человек или это была мультиподпись, валидатор не замети тэтой разницы. Это положительно влияет на приватность, ведь нельзя соотнести общий открытый ключ с конкретными субъектами.

В итоге

Схема Шнорра, это одна из наиболее эффективных и теоретически обоснованных схем аутентификации. Она оказалась не очень популярна из-за продолжительного патента, продолжающегося вплоть до 2008 года. Схема хоть претерпела некоторые изменения с момента создания, но её основные идеи остались не тронутыми и высоко ценятся в криптографии.

Источники

Подробнее..

Праздник к нам приходит проектируем и программируем световое шоу в xLights

29.12.2020 14:10:26 | Автор: admin

Ранее мы рассказывали про историю протоколов управления световым оборудованием. Настало время сделать свое шоу!

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

Для создания собственного светового шоу требуются умные источники света и пульт управления. Наиболее доступное решение использование адресных светодиодных лент на базе WS2818b и микроконтроллера с Wi-Fi. Подробную инструкцию по работе с адресной светодиодной лентой можно найти в блоге AlexGyver, а программную часть взять у проекта WLED.

В современных домашних инсталляциях для управления светом удобнее всего использовать Wi-Fi и протокол E1.31, а в качестве программы для создания шоу xLights. Мы решили пойти дальше и разработать собственное E1.31-совместимое устройство и запрограммировать с его помощью небольшое светопреставление. Выбор пал на Minecraft.

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

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

Протокол E1.31


Хотя Art-Net проще, мы выбрали стандартизированный sACN (E1.31). В интернете можно найти реализацию для языков C, C#, Python. Java не лучший язык для обработки байтового потока, но другого не надо. Необходимая нам функциональность получение пакетов E1.31 и извлечение необходимых данных, поэтому мы напишем свой приемник. Пакеты sACN отправляются по UDP и состоят из трех слоев. Структура пакета в нотации языка С, взятая из libe131:

/* E1.31 Packet Type *//* All packet contents shall be transmitted in network byte order (big endian) */typedef union {  PACK(struct {    PACK(struct { /* ACN Root Layer: 38 bytes */      uint16_t preamble_size;    /* Preamble Size */      uint16_t postamble_size;   /* Post-amble Size */      uint8_t  acn_pid[12];      /* ACN Packet Identifier */      uint16_t flength;          /* Flags (high 4 bits) & Length (low 12 bits) */      uint32_t vector;           /* Layer Vector */      uint8_t  cid[16];          /* Component Identifier (UUID) */    }) root;    PACK(struct { /* Framing Layer: 77 bytes */      uint16_t flength;          /* Flags (high 4 bits) & Length (low 12 bits) */      uint32_t vector;           /* Layer Vector */      uint8_t  source_name[64];  /* User Assigned Name of Source (UTF-8) */      uint8_t  priority;         /* Packet Priority (0-200, default 100) */      uint16_t reserved;         /* Reserved (should be always 0) */      uint8_t  seq_number;       /* Sequence Number (detect duplicates or out of order packets) */      uint8_t  options;          /* Options Flags (bit 7: preview data, bit 6: stream terminated) */      uint16_t universe;         /* DMX Universe Number */    }) frame;    PACK(struct { /* Device Management Protocol (DMP) Layer: 523 bytes */      uint16_t flength;          /* Flags (high 4 bits) / Length (low 12 bits) */      uint8_t  vector;           /* Layer Vector */      uint8_t  type;             /* Address Type & Data Type */      uint16_t first_addr;       /* First Property Address */      uint16_t addr_inc;         /* Address Increment */      uint16_t prop_val_cnt;     /* Property Value Count (1 + number of slots) */      uint8_t  prop_val[513];    /* Property Values (DMX start code + slots data) */    }) dmp;  });  uint8_t raw[638]; /* raw buffer view: 638 bytes */} e131_packet_t;


Нам интересны следующие поля:

  • номер последовательности seq_number;
  • номер DMX Universe universe;
  • количество байт DMX-информации в данном пакете prop_val_cnt;
  • байты DMX-информации prop_val;

Так как данные отправляются с большой частотой и по ненадежному UDP, то перепутать пакеты местами достаточно просто. Значение seq_number обозначает номер последовательности и фактически обозначает номер кадра в световом шоу, позволяя отбрасывать пакеты с номером меньше актуального. Значение universe помогает упорядочивать пакеты внутри кадра.

Обратите внимание, что один E1.31-пакет может содержать не больше 511 байт полезной информации. Согласно стандарту DMX, нулевой байт, называющийся стартовым кодом, зарезервирован и должен быть равен нулю.

При наличии более одной DMX-области полученные пакеты необходимо упорядочить и объединить DMX-данные, удалив нулевой байт из каждой DMX-области. Полученные DMX-данные можно использовать для управления освещением.

Настраиваем xLights


xLights свободно распространяемое программное обеспечение для управления DMX-контроллерами. Данная программа поддерживает Windows, Linux и macOS. На момент написания статьи на странице загрузки актуальная версия 2020.56.

Стартовое окно xLights

Сперва необходимо подключить все доступные контроллеры. Контроллер это устройство, которое принимает пакеты E1.31, извлекает из них данные и отправляет подключенным DMX-устройствам. В нашем случае контроллер один сервер Minecraft. Однако если вы используете светодиодные ленты, то скорее всего у каждой ленты будет свой контроллер.

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

Мы используем E1.31, поэтому выбираем Add Ethernet и в правой половине указываем необходимые для подключения данные: IP-адрес, протокол E131, номер начальной DMX-области и количество областей.

Количество областей напрямую зависит от количества каналов. Так, при использовании светодиодной ленты WS2812B каждый светодиод требует три канала. Таким образом, одна DMX-область может управлять только 170 светодиодами. Если светодиодов больше, то данному устройству нужно выделить больше DMX-областей.

Добавление контроллера

После указания всех необходимых данных нажимаем на кнопку Save, которая окрашивается в красный цвет при наличии несохраненных изменений. Мы указали две DMX-области по 510 каналов (511 вместе со стартовым кодом). Число 510 выбрано неслучайно, оно кратно трем, а все RGB-устройства имеют количество каналов, кратное трем.

Обратите внимание, что настройки контроллеров и композиции сохраняются в каталог, который указан как каталог шоу (Show Directory).

После настройки контроллеров можно переходить к настройке композиции.

Организация композиции


Вкладка Layout

Переходим на вкладку Layout в xLights. На данной вкладке можно видеть три области:

  • список моделей (левая верхняя четверть);
  • настройки выделенной модели (левая нижняя четверть);
  • внешний вид инсталляции (правая половина).

При первом открытии ни одна модель не выделена, а в настройках доступны параметры композиции. В параметре Background Image можно указать изображение, например, фотографию дома, квартиры или любого места, которое планируется для организации шоу.

Для добавления устройства в композицию необходимо выбрать его тип, а затем нарисовать его в окне композиции. По умолчанию xLights предоставляет базовые элементы и несколько сложных фигур. Тем не менее, предусмотрена возможность создания собственных моделей и отправки сырых DMX-данных.

Пример заполненной композиции. Выделена модель Common lightning.

Доступные настройки зависят от типа используемой модели. Наиболее интересным моментом является сопоставление моделей контроллерам. В нашем случае используется один контроллер, поэтому модели занимают каналы по возрастанию в порядке добавления в композицию. При использовании нескольких контроллеров необходимо явно указывать, кто управляет моделью в параметре Start Channel.

Также рекомендуется уделить должное внимание параметру Name, который задает имя модели в xLights. Грамотное назначение имен впоследствии несколько облегчит процесс программирования шоу.

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

Моделей, которые предоставляет xLights, достаточно для создания первых композиций. В меню добавления моделей есть кнопка с иконкой скачивания. Это позволяет загрузить готовые модели из разных источников. Тем не менее, иногда возникает необходимость в собственных моделях. Для этого случая есть два вида решения:

  • Custom (иконка с мордашкой);
  • DMX (иконка с цветным текстом DMX).

Модель типа Custom позволяет создавать световые устройства с собственной разметкой. Для этого необходимо добавить в композицию модель Custom, затем в настройках найти параметр Model Data в группе Custom и открыть редактор модели нажатием на троеточие.

Редактор модели Custom

Модель типа Custom позволяет создавать трехмерные модели с различной адресацией источников света в модели. Создание собственной модели представляет собой заполнение номеров управляющего канала в таблицах. Обращаем внимание, что данный редактор подразумевает использование однородных элементов в модели. Иными словами, все светильники в модели должны использовать одинаковое количество каналов. По умолчанию используются RGB-светильники, которые используют по три канала. Так мы разметили девять источников света, но модель потребляет 27 каналов.

Выбор типа DMX-устройства

В случае, когда тип Custom не способен решить проблему, например, используется DMX-совместимое не световое оборудование, на помощь приходит модель типа DMX. xLights имеет некоторое представление о не световых DMX-устройствах и предлагает выбрать тип устройства из списка. Если используемое устройство не присутствует в списке, то стоит выбрать General и указать количество используемых каналов и их названия в настройках модели в параметре Strand/Node Names. Мы использовали генератор огня, который принимает значения высота огня в блоках и продолжительность огня.

После создания композиции можно приступать к программированию шоу.

Создание шоу



Вкладка Sequencer

Создание шоу наиболее времязатратное действие. Переходим на вкладку Sequencer. Большинство элементов интерфейса будут неактивны, так как последовательность не создана. Последовательность создается через File New Sequence или комбинацией клавиш Ctrl+N.

В первую очередь xLights задаст вопрос о типе последовательности. Это может быть музыкальное шоу (Musical Sequence) или анимация (Animation). Первый тип требует указать музыкальный файл, который будет использоваться в светопреставлении. Вне зависимости от выбранного типа необходимо указать кадровую частоту для шоу. По умолчанию предлагаются значения 20 или 40 кадров в секунду. Данная настройка напрямую зависит от способности оборудования работать с требуемой скоростью. Мы рекомендуем начинать с 20 кадров в секунду.

Последним вопросом при создании шоу будет выбор моделей.

Вкладка Sequencer после создания композиции

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

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

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

На вкладке Sequence есть несколько окон:

  • Model Preview;
  • House Preview;
  • Color;
  • View;
  • Effect Settings;
  • Layer Blending;
  • Layer Settings.

Нам интересны только первые пять. Окно Model Preview позволяет увидеть, как выделенная на шкале времени модель отображает эффект, а House Preview позволяет увидеть все модели в контексте композиции.

С помощью окна Color можно задать разрешенные для модели цвета. По умолчанию xLights предполагает, что используются RGB-светильники, и разрешает использовать все цвета. Если вы хотите запретить какие-то цвета, необходимо снять отметки и нажать кнопку Update.

Окна View и Effect Settings позволяют указать время воспроизведения эффекта и задать его параметры. Мы не будем рассказывать про каждый эффект и его настройки, оставим это зоной для ваших экспериментов. Если эффект нравится в предпросмотре xLights, его можно вывести на контроллеры и посмотреть результат вживую.

В окне Effect Settings также присутствует кнопка Update. Ее следует нажимать, если модель, которая воспроизводит эффект, изменилась, иначе может быть некорректное отображение эффектов.

Настройки эффекта DMX

Ранее мы упоминали про DMX-совместимые устройства, которые не являются световым оборудованием, но могут управляться через xLights. В нашем случае это генератор огня, требующий два канала. Если каналы устройства были подписаны при создании композиции, то они отобразятся в настройках эффекта DMX.

Демонстрация эффекта DMX на генераторе огня

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

Демонстрация результатов


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


Плагин для Minecraft все еще в разработке, но его исходный код уже доступен в репозитории на github.com.

Заключение


Мы кратко рассмотрели процесс создания светового шоу в xLights. Если вас заинтересовала данная тема, то рекомендуем к ознакомлению сайт xlights.org. Там можно найти инструкции и людей, которые могут ответить на вопрос как на форуме, так и в Zoom.
Подробнее..

Чаты на вебсокетах, когда на бэкенде WAMP. Теперь про Android

13.01.2021 22:20:55 | Автор: admin

Мой коллега уже писал про наш опыт разработки чатов на вебсокетах для iOS, поэтому часть про особенности бэкенда с точки зрения клиента у нас общая. А вот реализация на Android, конечно, отличается. И ещё мне не приходилось, как в первой статье, искать библиотеку для поддержки старых версий операционной системы, потому что на Android каких-то глобальных изменений в сетевой части не было, всё работало и так.

К реализации вернёмся чуть ниже, а начнём с ответов на вопросы про бэкенд, которые появились после первой статьи: почему WAMP, какой брокер используем и некоторые другие моменты.

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

Что там на бэкенде

Почему WAMP. Изначально искал открытый протокол, который мог бы работать поверх WebSocket с поддержкой функционала PubSub и RPC и с потенциалом масштабирования. Лучше всего подошёл WAMP одни плюсы, разве что не нашёл реализации протокола на Java/Kotlin, которая бы меня устраивала.

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

К небольшим проблемам реализации проекта чатов можно отнести то, что нужно было ресёрчить и ревёрсить то, как работает реализация на Sendbird сервисе, который мы использовали. То есть какими возможностями мы там пользовались и какой дополнительный функционал был реализован поверх. Также к сложностям отнёс бы перенос данных из Sendbird в свою базу.

Ещё был такой момент в комментариях:

Правильно, что не стали использовать Socket.IO, так как рано или поздно столкнулись бы с двумя проблемами: 1) Пропуск сообщений. 2) Дублирование сообщений. WAMP к сожалению также не решает эти вопросы. Поэтому для чатов лучше использовать что-то вроде MQTT.

Насколько я могу судить, протокол не решает таких проблем магическим образом, всё упирается в реализацию. Да, на уровне протокола может поддерживаться дополнительная информация/настройки для указания уровня обслуживания (at most/at least/exactly), но ответственность за её реализацию всё равно лежит на конкретной имплементации. В нашем случае, учитывая специфику, достаточно гарантировать надёжную запись в базу и доставку на клиенты at most once, что WAMP вполне позволяет реализовать. Также он легко расширяем.

MQTT отличный протокол, никаких вопросов, но в данном сравнении у него меньше фич, чем у WAMP, которые могли бы пригодиться нам для сервиса чатов. В качестве альтернативы можно было бы рассмотреть XMPP (aka Jabber), потому что, в отличие от MQTT и WAMP, он предназначен для мессенджеров, но и там без допилов бы не обошлось. Ещё можно создать свой собственный протокол, что нередко делают в компаниях, но это, в том числе, дополнительные временные затраты.

Это были основные вопросы касательно бэкенда после предыдущей статьи, и, думаю, мы ещё вернёмся к нашей реализации в отдельном материале. А сейчас возвращаю слово Сергею.

Клиент-сервер

Начну с того, что WAMP означает для клиента.

  • В целом протокол предусматривает почти всё. Это облегчает взаимодействие разработчиков клиентской части и бэка.

  • Кодирование всех типов событий в числах (PUBLISH это 16, SUBSCRIBE 32 и так далее). Это усложняет чтение логов разработчику и QA (сразу не догадаться, что значит прилетевшее сообщение [33,11,5862354]).

  • Механизм подписок на события (например, новые сообщения в чат или обновление количества участников) реализован через получение от бэкенда уникального id подписки. Его надо где-то хранить и ни в коем случае не терять во избежание утечек. Как это сделано (было бы сильно проще и подписываться и отписываться просто по id чата):client подписываемся на новые сообщения в чате [32,18,{},"co.fun.chat.testChatId"]backend [33,18,5868752 (id подписки)]client после выхода из чата отписываемся по id [34,20,5868752]

Для работы с сокетом использовали OkHttp (стильно, надёжно, современно, реализация ping-pong таймаутов из коробки) и RxJava, потому что сама концепция чата практически идеальный пример того самого event-based programming, ради которого Rx, в общем, и задумывался.

Теперь рассмотрим пример коннекта к серверу, использующему WAMP-протокол через OkHttpClient:

val request = Request.Builder()    .url(ChatsConfig.SOCKETURL)    .addHeader("Connection", "Upgrade")    .addHeader("Sec-WebSocket-Protocol", "wamp.json")    .addHeader("Authorization", authToken)    .build()val listener = ChatWebSocketListener()webSocket = okHttpClient.newWebSocket(request, listener)

Пример реализации ChatWebSocketListener:

private inner class ChatWebSocketListener : WebSocketListener() {override fun onClosed(webSocket: WebSocket, code: Int, reason: String) { connectionStatusSubject.onNext(ChatConnectionStatuses.NOTCONNECTED) //subject, оповещающий пользователей о состоянии коннекта (в UI нужен для отображения лоадеров, оффлайн-стейтов и так далее)}override fun onClosing(webSocket: WebSocket, code: Int, reason: String) { webSocket.close(1000, null)}override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) { onConnectionError("${t.message} ${response?.body}")}override fun onMessage(webSocket: WebSocket, text: String) { socketMessagesSubject.onNext(serverMessageFactory.processMessage(text)) //subject, через который идут все сообщения, которые в дальнейшем фильтруются для конкретных получателей (см. ниже)}override fun onOpen(webSocket: WebSocket, response: Response) { authorize() }}

Здесь мы видим, что все сообщения от сокета приходят в виде обычного String, представляющего собой JSON, закодированный по правилам WAMP протокола и имеющий структуру:

[ResultCode: Int, RequestId: Long, ArgumentsMap: JsonObject ]

Например:

[50, 7, {"type":100, "chats":[список чатов]}]

Декодирование и отправка сообщений

Для декодинга сообщений в объекты мы использовали библиотеку Gson. Все модели ответа отписываются обычными data-классами вида:

@DontObfuscatedata class ChatListResponse(@SerializedName("chats") val chatList: List<Chat>)

А декодирование происходит с помощью следующего кода:

private fun chatListUpdateInternal(jsonChatsResponse: JSONObject):ChatsListUpdatesEvent { return gson.fromJson(jsonChatsResponse.toString(), ChatsListUpdatesEvent::class.java)}

Теперь рассмотрим базовый пример отправки сообщения по сокету. Для удобства мы сделали обёртку для всех базовых типов WAMP сообщений:

sealed class WampMessage { class BaseMessage(val wampId: Int, val seq: Long, val jsonData: JSONArray) : WampMessage()  class ErrorMessage(val procedureId: Int, val seq: Long, val jsonData: JSONArray) : WampMessage() object WelcomeMessage : WampMessage() class AbortMessage(val jsonData: JSONArray) : WampMessage()}

А также добавили фабрику для формирования этих сообщений:

fun getCallMessage(rpc: String,         options: Map<String, Any> = emptyMap(),         arguments: List<Any?> = emptyList(),         argumentsDict: Map<String, Any?> = emptyMap()):WampMessage.BaseMessage { //[CALL, Request|id, Options|dict, Procedure|uri, Arguments|list] val seq = nextSeq.getAndIncrement() return WampMessage.BaseMessage(WAMP.MessageIds.CALL,               seq,               JSONArray(listOfNotNull(WAMP.MessageIds.CALL,               seq,               options,               rpc,               arguments,               argumentsDict)))}

Пример отправки сообщений:

val messages: Observable<WampMessage> = socketMessagesSubjectfun sendMessage(msgToSend: WampMessage.BaseMessage): Observable<WampMessage> { return messages.filter {   it is WampMessage.BaseMessage && it.seq == msgToSend.seq}    .take(1)    .doOnSubscribe {     webSocket.send(msgToSend.jsonData.toString())    }}

Сопоставление отправленного сообщения и ответа на него в WAMP происходит с помощью уникального идентификатора seq, отправляемого клиентом, который потом кладётся в ответ.

В клиенте генерация идентификатора делается следующим образом:

companion object { private val nextSeq: AtomicLong = AtomicLong(1)}fun getNextSeq() = nextSeq.getAndIncrement()

Взаимодействие с WAMP Subscriptions

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

  • обновление списка чатов;

  • новые сообщения в конкретном чате;

  • изменение онлайн-статуса собеседника;

  • изменение в составе участников чата;

  • смена роли юзера (например, когда его назначают модератором);

  • и так далее.

Клиент сообщает серверу о желании получать события с помощью следующего сообщения:

[SUBSCRIBE: Int, RequestId: Long, Options: Map, Topic: String]

Где topic это скоуп событий, которые нужны подписчику.

Для формирования базового события подписки используется код:

fun getSubscribeMessage(topic: String, options: Map<String, Any> = emptyMap()): WampMessage.BaseMessage { val seq = nextSeq.getAndIncrement() return WampMessage.BaseMessage(WAMP.MessageIds.SUBSCRIBE,                 seq,                JSONArray(listOfNotNull(WAMP.MessageIds.SUBSCRIBE,                                seq,                                options,                                topic)))}

Разумеется, при выходе с экрана (например, списка чатов), необходимо соответствующую подписку корректно отменять. И вот тут выявляется одно из свойств протокола WAMP: при отправке subscribe-сообщения бэкенд возвращает числовой id подписки, и выходит, что отписаться от конкретного топика нельзя нужно запоминать и хранить этот id, чтобы использовать его при необходимости.

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

private val subscriptionsMap = ArrayMap<String, Long>()private fun getBaseSubscription(topic: String): Observable<WampMessage> { val msg = wampClientMessageFactory.getSubscribeMessage(topic) return send(msg).map {   val subscriptionId = converter.getSubscriptionId((it.asBaseMessage()).jsonData)   subscriptionsMap[topic] = subscriptionId   subscriptionId}    .switchMap { subscriptionId ->      chatClient.messages.filter {       it.isMessageFromSubscription(subscriptionId)     }    }}

Так клиент ничего не будет знать об id, и для отписки ему будет достаточно указать имя подписки, которую необходимо отменить:

fun unsubscribeFromTopic(topic: String) { if (!subscriptionsMap.contains(topic)) {    return } val msg = wampClientMessageFactory.getUnsubscribeMessage(subscriptionsMap[topic]) send(msg, true).exSubscribe() subscriptionsMap.remove(topic)}

Это то, что я хотел рассказать про реализацию на Android, но если есть вопросы постараюсь ответить на них в комментариях. Напомню, что про чаты на вебсокетах в iOS мы уже писали вот здесь, а также готовим отдельную часть про бэкенд.

Подробнее..

Перевод FTP исполнилось почти 50 лет и ему пора на пенсию

20.10.2020 16:06:30 | Автор: admin

Возможно, протокол передачи файлов FTP и был когда-то одним из столпов раннего интернета. Но после 50 лет повсеместного использования его уход на покой, пожалуй, уже неизбежен




Пока вы пытались перестроить всю свою жизнь так, чтобы уместить её в своей крохотной квартирке в начале коронавирусного кризиса, вы могли пропустить эту небольшую новость: из-за того, что вирус повлиял практически на все сферы жизни, компания Google решила пропустить выпуск 82-й версии Chrome.

Кому какое дело, спросите вы? До этого есть дело пользователям FTP протокола передачи файлов.

Во время пандемии Google отложила планы убийства FTP, и недавно, когда всё более-менее успокоилось, компания объявила о возврате к намерению убрать поддержку протокола в 86-й версии Chrome, и полностью убить его в 88-й версии.

Mozilla рассказала о похожих планах для браузера Firefox, ссылаясь на соображения безопасности и возраст кода.

Это один из самых старых протоколов, всё ещё поддерживаемых популярными приложениями в интернете в следующем году ему стукнет 50 но эти приложения уже готовятся отказаться от него.

Давайте углубимся в историю FTP, сетевого протокола, продержавшегося дольше любого другого.

1971


Именно в этом году Абхай Бушан, студент магистратуры из MIT, родившийся в Индии, впервые разработал FTP. FTP появился через два года после telnet, и был одним из первых примеров рабочего набора приложений для сети, известной тогда под названием ARPANET ещё до появления электронной почты, Usenet и даже стека TCP/IP. FTP, как и telnet, до сих пор можно кое-где использовать, однако в современном интернете он потерял популярность в основном из-за проблем с безопасностью. Его место занимает зашифрованная альтернатива SFTP протокол передачи файлов, работающий на базе протокола SSH, по большей части заменившего telnet.

Возможно, неудивительно, что из всех программ, написанных для ранней сети ARPANET, именно FTP проложил себе дорогу в современность.

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

Различия в характеристиках терминалов обрабатываются системными программами хостов в соответствии со стандартными протоколами, пояснял он, цитируя как telnet, так и протокол удалённого запуска задач того времени. Однако вам, чтобы пользоваться удалёнными системами, необходимо разбираться в их особенностях.


Терминал телетайпа из эпохи ARPANET

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

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


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

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

Поэтому мы подумали почему бы не добавить в FTP пару команд, mail и mail file? Mail это обычные текстовые сообщения, mail file это вложение файла в сообщение, это то, что у нас есть сегодня, сказал он в интервью.

Естественно, Бушан был не единственным человеком, оставившим свой след в этом раннем фундаментальном протоколе. Бушан в итоге ушёл от работы учёного, получив место в компании Xerox. Созданный им протокол продолжал расти и развиваться уже без него, претерпел несколько обновлений в 1970-х и 1980-х годах через последовательность RFC, включая и реализацию с поддержкой TCP/IP.

С тех пор он претерпел несколько небольших изменений, призванных поддерживать его в актуальном состоянии и добавлявших поддержку более новых технологий, современная версия FTP появилась в 1985 году, когда Джон Постел и Джойс Рейнолдс разработали RFC 959, обновление предыдущих протоколов, являющихся основой современных программ, поддерживающих FTP. Примерно в то же время Постел и Рейнолдс также принимали участие в разработке системы доменных имён. В документе новая версия описывалась, как попытка исправить некоторые небольшие ошибки в документации, улучшить объяснение некоторых особенностей протокола, и добавить несколько необязательных команд. Но при этом именно эта версия задержалась надолго.

Из-за возраста протокола у FTP есть множество слабых мест, часть из которых вылезают и по сей день. К примеру, передача директории с кучей маленьких файлов идёт чрезвычайно неэффективно передача больших файлов проходит гораздо лучше, поскольку протокол ограничивает количество отдельных соединений.

Поскольку протокол появился так давно, он во многом определил многие последующие протоколы. Его можно сравнить с чем-то, что часто скачкообразно обновляется в течение десятилетий допустим, с баскетбольной обувью. Конечно, кеды Converse All-Stars до сих пор можно считать хорошей обувью, и они могут хорошо показать себя в определённых условиях и сегодня, однако для профессиональных баскетболистов, скорее всего, лучше подойдёт что-нибудь от Nike с брендом Air Jordan.

FTP это кеды Converse All-Star интернета. Он передавал файлы ещё до того, как это стало круто, и до сих пор сохранил часть тех эмоций.

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

Алан Эмтейж, создатель первого поискового сервиса Archie, рассуждает в интервью блогу Internet Hall of Fame на тему того, почему его изобретение, позволившее пользователям искать файлы на анонимных FTP-серверах, не сделало его богатым. Если кратко, в то время интернет был некоммерческим, и Эмтейж, аспирант и сотрудник техподдержки монреальского университета Макгилла, использовал школьную сеть для работы Archie, причём без разрешения. Но так поступать было круто, рассказал он. Как говорится, легче просить прощения, чем разрешения. Эмтейж, как и Бушан, эмигрант он родился и рос на Барбадосе, а в Канаду приехал благодаря выдающейся успеваемости.



Почему FTP возможно, последняя связь с остатками прошлого, всё ещё существующего в онлайне


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

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

Во многих случаях эти сайты могут быть полезны, если у вас есть необходимость скачать что-то реально старое, типа драйвера или документации (мне это помогло, когда я подключал свою Connectix QuickCam).


Как сегодня выглядит FTP в браузере: ftp.logitech.com

В некоторых случаях ориентироваться на FTP бывает проще, чем на каком-нибудь сайте, поскольку интерфейс FTP последовательный и правильно работает. Через многие веб-интерфейсы бывает кошмарно сложно продраться, когда вам нужно просто скачать драйвер. Однако у простоты есть и обратная сторона FTP не так хорошо работает с современными стандартами, и выглядит более убого, чем современные методы передачи файлов.

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

В той статье было интервью с Джейсоном Скоттом из организации Internet Archive; они пытаются сохранять эти винтажные FTP-сайты, ведь любой из них может отключиться в любой момент.

Скотт тогда отметил, что долговременное существование этих FTP уже считается исключением из правила.

Очень странно, что у этих FTP-сайтов бывает инерция по 15-20 лет, и что они могли всё это время работать в неприкосновенности, сказал он.

И если одна из главных функций FTP-сайтов уходит в историю, возможно, их полное закрытие остаётся лишь вопросом времени. Рекомендую, пока этого не случилось, порыться в каком-нибудь из них, и посмотреть, какие странные штуки можно там отыскать. Мы уже не живём в мире, в котором можно просто порыться в директориях публичных компаний, и даже сегодня этот опыт остаётся интересным.

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

так говорится в статье журнала Network World за 1997 год, где доказывается, что несмотря на все недостатки FTP, это всё равно был нормальный вариант для многих удалённых работников и корпоративных пользователей. Конечно, статья была написана заинтересованным лицом Роджер Грин был президентом компании Ipswitch, крупного производителя программ для работы с FTP однако его аргументы в то время были справедливы. Это был отличный способ передавать крупные файлы по сетям и хранить их где-то на сервере. Проблема в том, что протокол FTP, пусть он и улучшался со временем, в итоге обогнали более сложные альтернативы как протоколы (BitTorrent, SFTP, rsync, git, даже современные варианты HTTP), так и облачные решения типа Dropbox или Amazon Web Services.

Когда-то давно и у меня был свой FTP-сервер. В основном я делился через него музыкой, учась в колледже в то время все студенты фанатели от музыкального обмена. У нас были очень быстрые каналы, благодаря чему это была идеальная среда для поддержки FTP-сервера.

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


Panic Transmit, современный пример FTP-клииента. Многие современные клиенты поддерживают множество протоколов кроме старого доброго FTP.

В итоге я съехал, и FTP-сервер закрылся навсегда в любом случае, появились более эффективные альтернативы, типа BitTorrent, и более легальные, типа Spotify и Tidal. Сожалению ли я сегодня о моём сервере? Конечно. Но в то время я чувствовал, что реализую некий протест, иду против системы. Конечно, ничего такого на самом деле не было.

Как обмен файлами претерпел изменения по сравнению с теми безрассудными временами 15-летней давности, так и мы выросли из использования былых FTP-серверов. Мы обучились более эффективным и безопасным техникам удалённой работы с файлами. В 2004 году было общепринятой практикой работать с веб-сервером через FTP. Сегодня, когда инструменты типа Git позволяют эффективно контролировать версии, такой подход считается рискованным и неэффективным.

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

В отличие от IRC, потерявшего популярность из-за коммерческих инструментов, и Gopher, переставшего развиваться после внезапного перехода на коммерческую модель, FTP уходит на пенсию потому, что его возраст подчёркивает отсутствие в нём безопасной инфраструктуры.

Некоторые из наиболее популярных примеров использования FTP-серверов, вроде публичных хранилищ файлов, вышли из моды. Однако основные варианты использования FTP уже заменили более безопасные и современные их версии, типа SFTP.

Я уверен, что какой-нибудь человек на технической должности будет заявлять, что FTP не умрёт никогда, поскольку для него всегда найдётся какой-нибудь особый вариант использования. Ну и ладно. Но большинство людей, когда Chrome выпилит поддержку FTP из браузера, вряд ли найдут причину заходить на FTP.

Если удаление поддержки FTP из браузера ускорит уход протокола, то так тому и быть. Однако за эти 50 лет в той или иной форме он отлично нам послужил.
Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru