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

#javascript #encryption #avatar #man-in-the-middle #avatar-generation

Вопрос:

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

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

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

Проблема:

Алиса и Боб принимают только идентификатор и открытый ключ, поэтому нет возможности просто и быстро отличить, есть ли между ними какая-либо связь, потому что 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. Идентикон http://identicon.net — генерирует двоичное изображение размером 5×5 с разными цветами. Дает 33554432*amount of colors , например, если есть все «веб-цвета» (216), то будет 33554432*216 = около 33 бит данных. Я знаю, что можно использовать больше цветов, но они становились менее различимыми, чем больше они добавлялись в список. Кроме того, эти значки не имеют смысла, выглядят как пятно Роршаха, и их нелегко запомнить при переключении вкладок браузера (между сообщением Alice в стороннем сервисе и фактическим сгенерированным значком в «защищенном приложении»).
  4. https://jdenticon.com/ — I cant actually count, how many images could be generated by this algorythm, but it hase a flaw like previous. In a sence, beautiful patterns sometimes couldn’t be recognized from each other.
  5. В Telegram зашифрованы звонки с использованием последовательности из четырех значков emoji. Как я обнаружил, в стандарте Unicode 3521 эмоция, поэтому четыре значка дадут: 3521*3521*3521*3521 = 153.696.543.348.481 = 47 бит данных, этот метод использует больше битов данных, чем аватары, и имеет не такую уж плохую легкость распознавания человеком. Если бы эти смайлики можно было объединить в какую-то «историю», распознавание было бы намного эффективнее, но тогда есть только четыре разных несвязанных изображения, это сохранится так, как если бы я использовал упомянутые сервисы аватаров для создания (например) четырех аватаров и размещения их вместе.
  6. Я попытался создать генератор изображений, там каждый пиксель задается одним байтом, так что 128 бит данных, или 16 байт, легко преобразуются в пиксельное изображение 4×4, но оно выглядит как визуальный шум и не может быть отличено от другого изображения.
  7. Я подумал о создании некоторого текстового представления UUID, например, используя четыре слова, объединенные случайным образом, но выглядящие как «История», например «<что?> <что?><кто?> <Делая что?> <Делая что?><с кем?>». Например, «синий гуникорн верхом на утке», «забавный молоток, приобретающий таблетку» и так далее. Но мне нужно будет снова создать списки прилагательных, существительных, глаголов и существительных, выбрав те, которые подходят для формулы. И у меня есть сомнения в том, что я смогу получить дополнительные биты данных с помощью этого метода.

Я что-то упускаю?

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

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

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

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

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

Ответ №1:

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

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

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