Шифрование личной переписки. Пятничный пост

Привет, Хабра! Тему шифрования личной переписки обсуждали уже много раз. Но по факту я не нашел ничего более менее вменяемого, чем бы мог пользоваться без геморроя. Поэтому написал свое расширение для соц. сетей с покером и куртизанками. Поскольку сегодня пятница, первая половина поста состоит из веселых историй с картинками. Во второй части — немного проблем и способов их решения.83ce064fd9afd5218b8f0e6e7a3a6388.pngЗачем нужно шифрованиеИстория о любвиa6b6ab893c7854ddcda0cc4835c5e905.png

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

История ревнивом муже

8aeb4bb2bee9a14be4280f95b18f3118.png

Сережа пишет Юле стихи о любви. Юля отвечает взаимностью. Кирилл грустит. Он муж Юли и что-то подозревает. Вскоре он прочтет переписку Сережи и Юли, и устроит ББПЕ своей жене. Юля могла бы съехать с темы и избежать ББПЕ, если бы больше знала о шифровании.

История об алиби

eb29d410cff45815ccfb1b4ae7ceaa7a.png

У Толика очень насыщенная жизнь. Как-то, в переписке по интернету, Толик хвастался своими приключениями. Теперь за эти приключения Толику могут предъявить. Этого могло бы не быть, если бы он шифровал свои подвиги.

История о массовых беспорядках

5679943dc38591bb4d75086834b7d22d.png

У Леши активная гражданская позиция. Леша любит собирать друзей и устраивать шумные собрания на городской площади. Гостей на эти собрания Леша приглашает через интернет. Программист Артём посмотрел все личные переписки, и быстро понял, кто является организатором массовых гуляний. Теперь у Леши проблемы. Он мог бы избежать их, если бы шифровал свои сообщения.

История об истеричке

553c70f9f5830c477d3155d81ed070de.png

Света прислала сообщение Глебу. Но Глеб встречается с Лидой. Глеб отошел в туалет, и забыл мобильник. Лида прочла сообщение Светы. Примерно через минуту Лида закатит скандал.

Как работает шифрование У Тимура есть чемодан и ключ. Он передает пустой чемодан своему другу Саше.1bf1402d2ecbffdab52b4bb5a9010c15.pngУ Саши тоже есть свой чемодан и ключ. Он делает их копию, и прячет в чемодан Тимура.40e2a395fea7b40a6da55137fe7dadf5.png

Т.к. назад чемодан возвращается в закрытом виде, открыть его может только Тимур. Только у Тимура есть ключ от его чемодана.11ce1798ec82804da1b0ab427affee6d.png

Тимур открывает свой чемодан и достает оттуда копию чемодана и ключа Саши.df14015400775c2fd49a6bc7cea38310.png

Теперь Тимуру больше не нужен свой чемодан и свой ключ. Он может пользоваться теми, что ему передал Саша.a2d0a1b0dc56f8c7fb0923a853fe52c8.png

Примерно так работает алгоритм шифрования RSA. А вот так выглядит быстрая расшифровка криптостойкого алгоритма с использованием терморектального криптоанализатора.6e070d85353538c30904d71e6d4ce850.png

Техническая сторона вопроса. В качестве алгоритма шифрования выбрал RSA. Несмотря на то, что алгоритму около 30 лет, первые попавшиеся библиотеки на JS оказались крайне плохого качества. Такое ощущение, что их писали исключительно для одного проекта. С трудом и болью смог приспособить их под нужды своего проекта, хотя задачи были типовые: Сгенерировать ключи Зашифровать текст открытым ключом Расшифровать текст закрытым ключом Так же был удивлен тем, что в половине аналогичных расширений, нужно придумывать какие-то фразы, как-то их передавать и т.д. Хотя, вроде уже давным-давно люди передают шифровки по открытым каналам, и процесс поддается автоматизации.

Проблемы парсинга соц. сетей. Начал с вконтакта. Первая трудность — на каждый диалог создается свое поле ввода и поле отображения сообщений. Проблема решилась получением id собеседника.Далее нужно было перехватить нажатие кнопки «Отправить» и кнопки Enter. Проблема в том, что вконтакт первый вешает события, и лишь потом инициализируется плагин. Чтобы исправить ситуацию добавил свои обработчики на document.body, а после фильтровал все перехваченные события. Нужно было первым получить их, чтобы успеть заменить оригинальное сообщение шифрованным.

Сайт одноклассники показал, что этого не достаточно. Максимальная длина сообщения у них составляет 3000 символов, а шифрованная пара ключей имеет длину 3800. Кроме того, обычные сообщения так же становятся длиннее за счет преобразования в base64. Пришлось написать механизм, который бы разбивал сообщения на части, подписывал их (id, текущий индекс, общее количество частей), а после собирал обратно. Получилось что-то вроде пакетов в TCP/IP.

Далее нужно было научиться генерировать событие «Отправить сообщение», т.к. скрипту нужно было самостоятельно отправлять пакеты. В вконтакте проблема решилась очень просто, через вызов глобального метода IM.send (). Чтобы добраться до области видимости сайта из области видимости расширения, пришлось добавлять тег SCRIPT и прописывать туда строкой вызов метода. Пример:

Тут следует пояснить, что DOM на сайт и расширение один и тот же, а глобальная область видимости — разная. В одноклассниках аналогичный метод найти не смог. Ребята минимизируют код и не плодят глобалы. Пришлось эмулировать событие на кнопке «Отправить»: var event = new Event («click», { bubbles: true, cancelable: true }); button.dispatchEvent (event); Когда текст был зашифрован, разбит на части, отправлен и собран, нужно было отличать новые и старые сообщения, которые отображаются на сайте. И вконтакте, и в одноклассниках они подписываются датой или уникальным id… думал я… Я ещё никогда так не ошибался. После этого возник «плавающий» баг. Оказалось, что все эти метки могут, так или иначе, совпасть для двух разных сообщений. Поэтому стал присваивать свой атрибут для всех DOM-узлов, чтобы знать кто уже обработан, а кто нет.Но чудеса на этом не закончились. Одноклассники публиковали сообщение, далее я его подменял расшифрованным, потом происходила какая-то магия, и через несколько миллисекунд одноклассники вновь писали оригинальный текст тот же HTML-элемент. Пришлось делать клон ноды сообщения, писать туда расшифровку, и скрывать оригинальный элемент. Оригинальная нода скрывалась (display: none), но не удалялась, т.к. я не знал, как и зачем её переписывают. Была опасность поломать скрипт одноклассников в случае удаления HTML-элемента.

Последняя загадка парсинга соц. сетей заключалась в том, что если с одного компьютера логинилось несколько людей, то их пары ключей для диалогов нужно было сохранять в разные места. Проблема решилась через извлечение ID текущего юзера. Знание ID юзера, сделало возможность создания персональных записей в localStorage:

rsa_keys__326374454 rsa_keys__43234223 rsa_keys__113234753 … Интересные наблюдения: Вконтакт и Фейсбук не сжимают CSS. В данный момент я затачиваю плагин и под фейсбук, и когда увидел в коде отсутствие id`шек и именование CSS-классов в стиле «l4y», опешил. Первая мысль была такая: «Они генерируют названия классов, следовательно, логика моего парсера рухнет на ближайшем обновлении и пересборке сайта.». Как оказалось, не рухнет. На ряду с короткими названиями, так же попадаются весьма длинные (например, «mdialog_chat_add-comment»). Видимо, у них в штате тоже есть говнокодеры, которые придумывают неочевидные и непонятные говно-названия. Несмотря на высокое качества кода одноклассников и закос под SPA-приложение, ребята не используют роутер и URL-страницы не меняется. Поэтому кнопка «назад» не работает, а о том, что сейчас отображается на экране, приходится догадываться из состояния DOM-дерева. Фейсбук, единственные, кто поленились писать крутое поле ввода. Только у них стоит обычная textarea, в которой все смайлы отображаются кодировкой, а не картинкой. Если я смог вас развеселить или заинтересовать, прошу на сайт http://bakhirev.biz/demo/crypto/. Там небольшая инструкция, ответы на вопросы и ссылка для установки. Буду рад баг-репортам, и новым пользователям.

© Habrahabr.ru