Создавайте различимые для человека изображения на основе строки (или uuid)

Tl;Dr: Я создаю приложение: чат со сквозным шифрованием между двумя или более пользователями, и мне нужен быстрый и удобный способ визуальной проверки отсутствия посредника.

Идея приложения:

  1. Интерфейсное приложение Алисы и Боба генерирует открытый и закрытый ключи RSA (с использованием библиотеки замечательнойjsencrypt )
  2. Интерфейсное приложение Алисы и Боба отправляет запрос на серверное приложение , поэтому сервер генерирует уникальный идентификатор для Алисы и Боба (на самом деле UUID).
  3. Интерфейсное приложение Алисы и Боба генерирует ссылку и QR-код , содержащие их открытые ключи и их идентификаторы в хэш-части URL-адреса, поэтому он не будет отправлен на сервер при открытии.
  4. Фотография ссылки или QR-кода затем может быть отправлена ​​сторонним каналом (незащищенным), и, будучи открытым, приложение интерфейса Алисы и Боба может добавить своего аналога в «список контактов» (все это происходит на стороне интерфейса). )
  5. Приложение Алисы после получения открытого ключа и идентификатора от приложения Боба шифрует сообщение открытым ключом и отправляет его на сервер , указывая идентификатор Боба.
  6. Боб спрашивает сервер «есть ли новые сообщения для моего ID?» И, получив сообщение с сервера, расшифровывает его своим закрытым ключом.
  7. Сервер не получает ни приватных, ни публичных ключей в любой момент. Он просто генерирует идентификатор и передает через себя сообщения между идентификаторами, зашифрованными интерфейсом javascript, не имея возможности его прочитать, и удаляет сообщение сразу после того, как оно было получено интерфейсом.

Проблема:

Алиса и Боб принимают только ID и открытый ключ, поэтому нет способа просто и быстро различить, есть ли между ними ManInTheMiddle, потому что UUID, в отличие от некоторых SHA-хэшей, обычно выглядит очень похоже. Последовательно сгенерированные идентификаторы uuid могут отличаться только одним символом, и человеческому глазу не так легко распознать эту разницу.

Желаемое решение:

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

Какая-то картинка, "аватар" пользователя была бы отличной.

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

Что я пробовал:

  1. Инструмент создания аватара https://getavataaars.com/ - позволяет создавать изображение аватара, основанное на 10 параметрах, каждый из которых содержит несколько вариантов, поэтому, если я умножу их все, я получу: 35*7*6*8*9*12*12*12*12*7= 15.362.887.680 -> 34 бита данных.на мой взгляд, это слишком мало. Но идея создания аватара мне понравилась.

  2. Инструмент генерации аватаров https://8biticon.com - аналогично предыдущему, имеет 5*4*65*26*36*32= 38.937.600 -> 26 бит данных

  3. Identicon http://identicon.net - генерирует двоичное изображение 5x5 разных цветов. Дает 33554432*amount of colors, например, если присутствуют все "веб-цвета" (216), будет 33554432*216= около 33 бит данных. Я знаю, что можно использовать больше цветов, но они становились менее различимыми, чем больше они добавлялись в список. Кроме того, эти значки не имеют смысла, выглядят как точка Роршаха, и их нельзя легко запомнить при переключении вкладок браузера (между сообщением Алисы в сторонней службе и фактическим сгенерированным значком в «защищенном приложении»)

  4. https://jdenticon.com/ - я не могу подсчитать, сколько изображений может быть сгенерировано этим алгоритмом, но у него есть недостаток, как и в предыдущем. В каком-то смысле красивые узоры иногда нельзя было отличить друг от друга.

  5. Telegram передает зашифрованные звонки с использованием последовательности из четырех значков эмодзи. Как я обнаружил, в стандарте Unicode 3521 эмоция, поэтому четыре значка дадут: 3521*3521*3521*3521= 153.696.543.348.481 = 47 бит данных , этот метод использует больше битов данных, чем аватары, и имеет неплохую легкость распознавания человеком. Если бы эти смайлики можно было объединить в какую-то «историю», распознавание было бы очень эффективным, но тогда есть всего четыре разных несвязанных изображения, это сохранение, как если бы я использовал упомянутые службы аватаров для создания (например) четырех аватаров. и сложить их вместе.

  6. Я попытался создать генератор изображений, где каждый пиксель указан одним байтом, поэтому 128 бит данных или 16 байтов легко конвертируются в пиксельное изображение 4x4, но оно выглядит как визуальный шум и не может отличаться от другого изображения .

  7. Я подумал о создании некоторого текстового представления UUID, например, используя четыре слова, объединенные случайным образом, но выглядящие как «История» типа «<что?> <Кто?> <Создание чего?> <С кем?>». Например «синий пулемет едет на утке», «забавный молоток достает пилюлю» и так далее. Но мне нужно будет снова создать списки прилагательных, существительных, глаголов и существительных, выбрав те, которые подходят для формулы. И я сомневаюсь, что этим методом я смогу получить новые данные.

Я что-то пропустил?

Может быть, есть еще какие-то алгоритмы, которых я еще не нашел?

Может быть, мне не нужно использовать все 128 бит, а просто создать хеш меньшего размера? Я читал о проблеме с сокращением хэша, и с усечением UUID есть очень серьезная проблема (поэтому, если будет использоваться усечение, необходимо сделать хэш UUID, а не использовать его «как есть»)

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

Также изображение на основе открытого ключа

Я думаю, что этого создания образа на основе идентификатора пользователя недостаточно, потому что более опасная ситуация возникает, когда ManInTheMiddle каким-то образом может подменить открытый ключ, поэтому сообщение, зашифрованное этим злым ключом, может быть расшифровано с помощью злого закрытого ключа. Но создание образа открытого ключа имеет проблемы с сохранением, добавляя размер открытого ключа (он может составлять около 1 Кбайта), поэтому для создания образа из открытого ключа мне определенно нужно получить его хэш sha256 (или другой), и строим образ из хеш-строки, там мы возвращаемся к исходной точке.

1 ответ

Отвечая на свой вопрос.

После множества экспериментов я решил использовать движок аватаров, который можно найти на https://getavataaars.com/ (на самом деле это версия VanillaJS: https://github.com/HB0N0/AvataaarsJs)

И, наконец, я сделал бета-версию приложения для зашифрованного чата: https://cryptboard.io/

Другие вопросы по тегам