Все началось с того что к нам в офис приехал директор иногороднего филиала.
Он подошел ко мне и сказал примерно следующее:
«Я переписываюсь с генеральным директором с помощью mail.ru.
В переписке мы обсуждаем весьма щекотливые вопросы, связанные, например, с …, ну тебе лучше не знать…. Я бы не хотел чтобы эта переписка была доступна третьим лицам.»
Я озаботился вопросом и достаточно быстро выяснил, что стандартом является шифрование с помощью шифра AES и аутентификация с помощью шифра RSA. Все мессенджеры предусматривают регистрацию, имеют свои сервера и хранят историю переписки.
Кроме того, я выяснил, что все существующие средства шифрования, которые доступны официально, должны иметь лицензию ФСБ (Постановление 313 https://base.garant.ru/70 164 728/). Одно из условий выдачи такой лицензии — предоставление ключей для доступа к переписке. (Вспоминаем историю с запретом Telegram в РФ).
То есть, использование любого, существующего легально, мессенджера не дает уверенности в тайне переписки.
Проанализировав ситуацию, я вывел рецепт идеального (защищенного) мессенджера.
Он должен состоять из следующих элементов:
Алгоритм шифрования с абсоютной криптостойкостью.
Надежный способ передачи ключей.
Надежный способ аутентификации (не RSA).
И не иметь своих серверов, не требовать регистрации, не хранить историю переписки.
Далее началась реализация.
Элемент 1. Шифр с абсолютной криптостойкостью.
Бытует мнение что взломать можно любой шифр. Хотя бы теоретически — брутфорсом.
И я почему‑то уверен, что мало кто из читателей этого текста знает что такое алгоритм Вернама. (По крайней мере, я не знал).
Он нигде не рекламируется и упоминается только в учебниках по криптографии, да и то не во всех.
А между тем, этот алгоритм запатентован Гилбертом Вернамом в далеком 1917 году.
В 1946 г. Клод Шеннон (по заказу министерства обороны США) доказал что шифр Вернама обладает абсолютной криптостойкостью.
Аболютная криптостойкость — это ситуация, когда все сообщения перехвачены, алгоритм шифрования известен, и, несмотря на это, вероятность угадывания каждого следующего бита не превышает 50% и не зависит от времени и компьютерной мощности, которые имеются в распоряжении криптоаналитика.
По‑простому, к алгоритму Вернама нельзя применить метод Brute‑force.
Алгоритм Вернама опубликован (https://ru.wikipedia.org/wiki/%D0%A8%D0%B8%D1%84%D1%80_%D0%92%D0%B5%D1%80%D0%BD%D0%B0%D0%BC%D0%B0), его реализация очень проста — бери и делай.
Основная трудность — обеспечить одноразовость и случайность ключей.
Так как в шифре Вернама длина ключа равна длине текста, то нужно сгенерировать достаточно длинную последовательность случайных чисел (чтобы потом от нее отщипывать одноразовые кусочки).
Генерация случайной последовательности — отдельная задача.
Я использовал свой вариант реализации алгоритма Blum‑Blum‑Shub.
Этот алгоритм хорошо изучен и стабилен. Но он дает псевдослучайную последовательность.
А нам нужна истинная случайность.
Поэтому, вторая задача — сделать из псевдослучайной последовательности истинно случайную (или максимально приблизиться к этому).
Эту задачу я тоже решил. Истинно случайную последовательность получаем из каракулей пользователя. А потом перемешиваем ее с псевдослучайной от Blum‑Blum‑Shub. Алгоритм перемешивания взял у Кнута, Дональда нашего.
Полученная таким образом длинная последовательность случайных чисел хранится на устройстве (в зашифрованном виде). Пароль (ключ) на расшифровку вводится при старте приложения — хранится в голове пользователя и кнопки «Забыли пароль?» там нет.
При утере, краже или захвате устройства злоумышленник не сможет воспользоваться вашим мессенджером потому что не знает пароль. Это первый уровень защиты.
Элемент 2. Надежный способ передачи ключей.
Самый надежный способ передачи ключей — личная встреча. Это аксиома. Для шифра Вернама передавать нужно довольно длинную последовательность. Но я придумал способ как сделать это с помощью QRcode. Партнеры встречаются (можно на 5 секунд) — один показывает QRcode на экране, второй — считывает. Все. И далее на обоих устройствах генерируется (идентичная) длинная последовательность.
Элемент 3. Надежный способ аутентификации (не RSA).
Американский институт стандартов (NIST), начиная с 2018 года, провел 4 конкуса на замещение уязвимого и ненадежного алгоритма RSA новым постквантовым алгоритмом.
Но я решал задачу очень узкую, когда два человека очень хотят обеспечить тайну переписки.
И здесь все просто. Этому в СССР учили детей (я застал). В фильме «Неуловимые мстители» есть соответствующий эпизод:
Здрасте! Вам билетёр требуется? — Был нужен, уже взяли. — А может, и я на что сгожусь?
При личной встрече партнеры договариваются о пароле и отзыве. Все. Никаких хитрых алгоритмов не нужно. В начале каждого сеанса связи вы посылаете сообщение‑пароль и ждете сообщение‑отзыв. Это второй уровень защиты.
Собственные сервера нужны мессенджерам для регистрации, хранения истории сообщений и всякой ерунды типа обмена статусами (ну и для сбора метаинформации — кто с кем и сколько раз).
Мне содержать собственные сервера не по карману (и обслуживать замучаешься).
Я использую чужие сервера, например — обычный бесплатный эккаунт DropBox.
Первый абонент создает файл с зашифрованным текстом и кладет его в некий DropBox эккаунт. Второй абонент (по таймеру) опрашивает и читает этот файл к себе на устройство, расшифровывает и предъявляет. Здесь нужно решить проблему синхронизации ключей. Она решается просто — в начале сообщения в незашифрованном виде прописывается номер первого байта ключа (в длинной последовательности) и длина ключа. На приемной стороне это считывается — из длинной поледовательности выкусывается этот кусок и используется для расшифровки.
В принципе, в качестве промежуточного места хранения может быть использован любой сервис хранения файлов (если у него есть соответствующий API).
Зашифрованный файл после этого стирается (чтобы место не занимал), а использованные ключи затираются. Это третий уровень защиты.
Со стороны это выглядит как один человек положил файл в DropBox, а другой прочитал.
Сообщение в незашифрованном виде существует только на экране мобильного устройства.
После перехода на другую страницу оно стирается. История сообщений нигде не хранится.
Никакой регистрации не требуется (данные для доступа в DropBox прописаны в коде).
Первый абонент сам создает новый контакт, где указывает псевдоним для себя и для партнера.
Для этого контакта создается свой QRcode, который показывается партнеру.
Партнер считвыает QRcode и у него появляется новый контакт (с псевдонимом первого абонента).
То есть никакого спама не может быть в принципе. У вас будут только те контакты, которые вы сами создадите.
В результате получаем аналог личной встречи (насколько это технически возможно).
Оставляем за скобками кейлоггеры и прочие видеокамеры за плечом.
Никаких следов не остается (за исключением зашифрованного файла на сервере интернет‑провайдера по закону Яровой).
Текст из одной головы попадает в другую голову. И все.
Криптоаналитик может перехватить все ваши сообщения (запросив их у интернет ‑провайдера), но расшифровать их он не сможет ни сегодня, ни завтра. Не сможет никогда в будущем, независимо от располагаемой компьютерной мощности.
Вот оно — Абсолютное Оружие! (https://rutube.ru/video/23 696bad699fd38 659bc2d66 918ef688/)
(Ну еще нужно было сделать всякие мелочи типа внедрить в приложение подсистему оплаты — она разная у Google и Apple).
Я хотел иметь единый исходный код для всех платформ, поэтому реализовал все на Xamarin (в 2018). Потом переписал все на.NET MAUI.
К слову сказать, единого кода таки не получилось. Android и iOS все‑таки разные.
Далее начался процесс продвижения.
Продавать мобильное приложение можно только через магазины Google и Apple.
Считается, что любое приложение в магазине — это (внезапно) собственность США, и чтобы продавать его на территории РФ нужно получить разрешение на экспорт (из США в РФ). Да, вот так вот.
Получить разрешение нельзя (или очень сложно), потому что сильное шифрование находится в том же разделе закона об экспорте что и оружие.
Ну ладно. Я решил что американского рынка мне должно хватить.
Открыл фирму в Канаде (чтобы американцы не пугались того, что изготовитель русский).
Опубликовал приложение в магазинах Google и Apple (от имени этой фирмы).
И стал присматривать себе уже квартиру в удобном месте и абонемент в массажный салон.
Но ничего не происходило. Вообще.
Денег на рекламу у меня не было.
Был сайт с приличной посещаемостью (англоязычный) — повесил на нем баннер — безрезультатно.
Приложение пролежало в магазинах с 2018 по 2022 год.
За это время несколько раз менялись разные условия и приходилось переписывать большие куски (например, у DropBox были долгоживущие ключи доступа, а потом их отменили и пришлось перегенерировать ключи всякий раз).
Отдельная эпопея — это Push Notifications.
Я потратил весьма много энергии и времени и звоночек стал звонить, но потом решил что это оставляет лишний цифровой след и отказался.
В 2022 году возникли сложности с магазинами.
Кроме этого оказалось, что каждый владелец зарубежной фирмы должен ежегодно предоставлять в налоговую специфический отчет (КИК), который сделать самому нереально, а юридические фирмы берут за него мнэ‑э-э — лучше не знать. А штраф за неподачу в срок — 2 миллиона рублей.
Сугубо не рекомендую открывать зарубежные фирмы (если вы не миллионер и у вас нет своего юридического отдела).
Свою я срочно аннулировал и на этом гештальт был закрыт.
Уфф…
Вероятные причины провала продаж.
Банальная нехватка денег на рекламу.
Это асоциальный мессенджер. Он не предназначен для «поболтать». Он нужен тогда когда нужна замена личной встречи. То есть целевая аудитория специфична.
Разделять секреты с незнакомыми людьми глупо.
Я думаю, что это может быть востребованным у таких категорий людей как
близкие родственники (супруги)
партнеры по бизнесу
босс и подчиненные
врачи и клиенты
обвиняемые и адвокаты
военные (шпионы)
обязательно должны заинтересоваться криминальные структуры, но им я не продам технологию.
Что теперь?
Согласно Постановлению 313, я не могу продавать свое решение на территории РФ легально.
Но консультационные услуги оказывать могу.
Если вам очень нужно — вы можете обратиться ко мне — я научу вас как написать код и вы сможете сделать приложение для собственнных нужд (что не запрещено).
При этом у вас будет полная уверенность в том что в коде нет «закладок» (ведь код будете писать вы или ваши доверенные программисты).
Если у вас есть секреты и вы готовы тратить время и деньги на их защиту — обращайтесь.
Почта для заявок: mal0@mail.ru
----------------------------------------------------------------------
Ну вот, прошла неделя, страсти поулеглись и я считаю возможным дать ответы на вопросы и критику.
В любом случае благодарю всех, кто потратил свое время на обсуждение.
Я обычный инженер-программист широкого профиля и решал вполне ограниченную инженерную задачу:
1 сделать работающее решение, максимально приближенное к алгоритму Вернама при условии отсутствия аппаратного генератора случайных чисел
2 для передачи ключей использовать личную встречу
3 обеспечить многоплатформенную реализаци
4 обойтись без своего сервера
Также обозначим область определения.
Те кто считает Windows/Android/iOS ненадежными по определению, могут сразу покинуть дискуссию.
Я в тексте статьи написал что оставляю за скобками кейлоггеры и телекамеры за плечом.
К слову сказать, на рынке присутствует масса мессенджеров с криптозащитой и мой вариант в этом плане не хуже.
Начну с того что я понял что многие меня неправильно поняли.
В QR-Code я передаю GUID канала, псевдонимы абонентов, 3 (больших) простых числа для затравки BBS и массив из 2000 бит, полученный из линии, нарисованной пользователем. Далее оба абонента из этих данных генерируют (идентичную) длинную последовательность, которая есть результат перемешивания псевдослучайной последовательности от BBS и истинно случайной последовательности, полученной из линии, нарисованной пользователем.
Рассмотрим суть претензий.
1 Узкая целевая аудитория.
Согласен.
Об этом и статья - когда предлагается действительно что-то близкое к идеалу, то оказывается что это особо никому не нужно (потому что нужно немного заморочиться).
2 Слишком сложно.
Я стремился минимизироваться сложность.
Пользователь должен
Придумать и запомнить парольную фразу - ключ для шифрования длинной последовательности.
Придумать и запомнить пароль - отзыв (для каждого абонента)
Нарисовать на экране какие-то каракульки общей длиной 2000 точек (занимает около 30 сек).
Лично встретится с абонентом чтобы тот сосканировал QR-Code и чтобы договориться с ним о пароле-отзыве.
На мой взгляд не очень сложно.
Тут вопрос ценности секретов.
Если вы не готовы немного понапрягаться, значит ваши секреты не стоят этих усилий.
3 Почему Блюм-Блюм-Шуб. Есть более криптостойкие алгоритмы (мне рекомендовали ChaCha20).
Не настаиваю.
Вы можете использовать любой алгоритм какой сочтете нужным.
4 Для шифра Вернама нужна последовательность истинно случайных байт.
Да, это так.
И ограничением является отсутствие аппаратного генератора случайной последовательности.
Истинно случайную последовательность я (как разработчик ПО) могу получить только от пользователя.
Я предлагаю нарисовать каля-маля. Из полученной линии получаю массив из 2000 битов.
Далее я как-бы умножаю порядок на хаос (перемешиваю псевдослучайную последовательность истинно случайным образом).
В результате получаю последовательность, которую (на мой взгляд) весьма трудно отличить от истинно случайной.
По крайней мере, стандартный тест NIST SP800-22rev1a (https://csrc.nist.gov/pubs/sp/800/22/r1/upd1/final) выдает вот такие результаты
RESULTS FOR THE UNIFORMITY OF P-VALUES AND THE PROPORTION OF PASSING SEQUENCES
generator is <\Mac\Home\Documents\nist\keys1.dat>
C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 P-VALUE PROPORTION STATISTICAL TEST
6 10 14 13 7 11 10 9 9 11 0.798139 1.000 Frequency
12 9 10 13 10 5 12 10 9 10 0.883171 0.990 BlockFrequency
6 15 13 13 9 12 7 11 5 9 0.350485 1.000 CumulativeSums
5 15 12 11 8 8 11 11 9 10 0.678686 1.000 CumulativeSums
9 10 10 16 9 17 9 6 7 7 0.202268 1.000 Runs
11 5 7 11 10 7 13 15 7 14 0.319084 1.000 LongestRun
5 11 9 10 6 12 8 7 13 19 0.090936 0.980 Rank
12 13 11 9 12 6 12 8 14 3 0.289667 0.990 FFT
12 7 9 8 11 13 8 9 13 10 0.897763 0.980 OverlappingTemplate
8 4 12 12 10 11 17 10 7 9 0.289667 1.000 Universal
12 8 6 9 12 7 9 18 10 9 0.319084 1.000 ApproximateEntropy
6 8 8 5 8 7 4 3 8 3 0.671779 0.983 RandomExcursions
2 7 9 5 7 8 6 8 3 5 0.568055 0.983 RandomExcursions
8 2 9 12 7 3 4 7 4 4 0.100508 0.983 RandomExcursions
9 8 5 5 7 5 9 3 4 5 0.671779 0.967 RandomExcursions
6 7 8 3 9 7 3 3 9 5 0.468595 1.000 RandomExcursions
5 4 5 11 4 7 11 1 6 6 0.110952 0.967 RandomExcursions
6 12 8 3 4 6 3 3 9 6 0.148094 0.983 RandomExcursions
10 6 7 5 4 7 5 4 3 9 0.568055 0.950 RandomExcursions
8 2 6 4 9 2 6 7 6 10 0.275709 0.983 RandomExcursionsVariant
7 2 5 4 5 7 5 6 9 10 0.500934 0.983 RandomExcursionsVariant
6 5 3 6 4 6 13 5 10 2 0.066882 0.967 RandomExcursionsVariant
7 5 3 6 5 5 12 8 5 4 0.378138 0.967 RandomExcursionsVariant
7 4 8 7 4 4 4 6 11 5 0.534146 1.000 RandomExcursionsVariant
6 9 4 8 3 6 4 5 8 7 0.739918 1.000 RandomExcursionsVariant
4 10 7 5 2 7 6 8 6 5 0.602458 1.000 RandomExcursionsVariant
5 6 9 4 4 6 8 5 6 7 0.911413 1.000 RandomExcursionsVariant
8 2 5 9 6 6 5 12 5 2 0.122325 0.967 RandomExcursionsVariant
8 9 3 4 4 7 8 9 5 3 0.437274 0.983 RandomExcursionsVariant
11 6 6 3 3 10 4 8 5 4 0.213309 0.950 RandomExcursionsVariant
8 7 7 7 3 5 7 7 5 4 0.911413 0.967 RandomExcursionsVariant
5 6 4 10 7 8 5 4 6 5 0.804337 0.967 RandomExcursionsVariant
5 4 4 5 12 7 8 6 6 3 0.350485 0.983 RandomExcursionsVariant
6 3 6 7 6 7 9 8 3 5 0.772760 0.983 RandomExcursionsVariant
4 5 6 8 4 8 9 7 5 4 0.804337 0.983 RandomExcursionsVariant
6 4 6 6 6 9 9 2 3 9 0.407091 1.000 RandomExcursionsVariant
5 6 5 3 10 5 7 5 8 6 0.772760 1.000 RandomExcursionsVariant
12 10 6 6 10 11 10 11 11 13 0.851383 0.970 Serial
15 7 6 10 10 15 7 8 8 14 0.289667 0.970 Serial
11 10 6 6 13 11 13 8 9 13 0.678686 0.960 LinearComplexity
Смотрим на колонку P-Value и видим что везде значение больше 0.01, что доказывает истинность так называемой нулевой гипотезы.
Для неспециалистов - нулевая гипотеза предполагает что исследуемая последовательность является истинно случайной.
Какие претензии?
На всякий случай еще момент - у алгоритма BBS (как и у любого алгоритма генерации псевдослучайных чисел) есть период.
В частности, период последовательности BBS для выбранных двух 9-значных простых чисел (я использую 9-значные) примерно равен:
8.3×10^14. Ну, то есть, я до периода сильно не дотягиваю.
И да, я согласен с тем что это не истинно случайная последовательность и ее можно (теоретически) подобрать брутфорсом.
Хотя, брутфорс для Вернама не применим, но представим что применим.
Количество вариантов = число сочетаний по 3 из миллиона (я храню миллион простых чисел и всякий раз выбираю случайно 3 штуки для генерации BBS)= 1.67 × 10^17 и умножить на 2^2000 = 10^602.
Итого 1.68 х 10^619 степени.
Для сравнения количество атомов во Вселенной (говорят) 10^80.
И я же написал в статье - это не чисто случайная последовательность, а последовательность, максимально приближенная к случайной.
Решая инженерные задачи, приходится мириться с неидеальностью.
5 Сгенерированную длинную последовательность нужно хранить на устройстве и защищать от компрометации.
Да.
При запуске приложения пользователю предлагается придумать - фразу-ключ шифрования этой длинной последовательности.
Длинная последовательность шифруется этой фразой (по-простому - тем же XOR).
Рассмотрим вариант кражи устройства.
Похититель может заняться брутфорсом, но попыток у него будет ровно одна, потому что есть пароль-отзыв, которого он не знает.
6 Если Боб и Алиса лично встречаются, нет смысла шифрования: вместо маски шифра просто передаёте сообщение.
Поясняю.
Абоненты лично встречаются однократно, когда им еще нечего передавать.
В результате у них создается идентичная последовательность байтов, из которой потом выкусываются одноразовые ключи.
Один раз встретился - потом всю жизнь посылай сообщения.
7 А как синхронизировать смещение для каждого нового сообщения?
Я сделал просто. В начале каждого сообщения в незашифрованном виде передается номер первого байта ключа в длинной последовательности.
Мне уже прислали возмущенное письмо по поводу того что любой злоумышленник сможет это число подменить что разрушит целостность канала.
Ну да.
Я решал задачу защиты от перехвата, а не от этого.
Будет ТЗ на эту атаку - придумаю что-нибудь.
8 DropBox ненадежен.
Не понимаю претензии.
Положить файл - прочитать файл. Простейшая (а значит надежная) операция.
Хотя, вы можете использовать для промежуточного хранения любой сервис обмена файлами.
Просто у дропбокса в API были нужные мне функции.
9 Если rsa не нравится, то постквантовый kyber
Повторю, речь идет о событиях 2018 года. kyber - это 2024.
И еще раз. Я принял за аксиому что самый надежный способ передачи ключей - это личная встреча.
Если для кого-то это не аксиома - используйте RSA или его постквантовые заменители.
Итого.
Я поделился тем как я решал инженерную задачу реализации схемы Вернама без аппаратного генератора случайных чисел.
В частности, как я решил проблему генерации длинной последовательности весьма близко приближеннной к истинно случайной.
И еще в частности, как я решил проблему передачи ключей (вернее не ключей, а данных для генерации ключей).
Кто может предложить более лучшие (по каким-то критериям) способы - предлагайте.