Как уязвимость в Яндекс.Станции вдохновила меня на проект: Музыкальная передача данных
На прошлой неделе я рассказал, как устроена активация Яндекс.Станции через звук. Оказалось, что пароль от WiFi передаётся в открытом виде. Я размышлял, зачем вообще нужно было делать активацию так, а не каким-то отлаженным способом.
В итоге, пришел к выводу, что в этом процессе важно шоу. Но, что будет, если сделать протокол передачи данных, полностью ориентированный на впечатление пользователя? Так родился проект «Octave» — для мелодичной передачи данных.
Под катом я расскажу, как сделан прототип, и дам ссылку на демку. Вы сможете сами послушать, как звучит любое сообщение:)
Краткое содержание предыдущей статьи
Я записал звук, которым активируется Станция, посмотрел на визуализацию скользящего преобразования Фурье и понял, как устроен сигнал и где лежит пароль от WiFi в открытом виде.
Передаётся hex-строка, где для каждого символа 0 — F есть своя частота 1 кГц — 4,6 кГц с шагом в 240 Гц. Я размышлял, зачем нужно было делать активацию так, а не через Bluetooth, как например у китайских пылесосов-роботов, и пришел к выводу, что в данном случае эффектность важна больше, чем безопасность или скорость.
Вдохновение
Действительно! Ведь протокол связи — всегда компромисс между дальностью, скоростью и надежностью. А что если все эти характеристики отойдут на второй план, а определяющим станет фактор впечатления для пользователя?
Мне понравилась простая, как молоток, идея разработчиков Яндекса — выбрать 16 частот: по одной для каждого hex-символа. А еще у меня был приёмник сигнала с прошлого исследования, поэтому я решил развить эту идею, а не придумывать все с нуля.
Два улучшения
Убираем разрыв фазы
Во-первых, когда я анализировал сигнал активации Станции, меня смутил шум на всех частотах в момент переключения символа. Это вертикальные полосы на спектрограмме:
В эти моменты слышно щелчки. Причина данного эффекта — разрыв фазы между символами. Дело в том, что в длину одного символа укладывается не целое число периодов звуковых колебаний. Поэтому, в момент переключения частоты амплитуда сигнала резко меняется. Примерно так:
В радио есть разные методы, позволяющие избежать этого эффекта. Я же решил плавно уменьшать амплитуду сигнала к моменту переключения частоты, а затем плавно наращивать — это звучит более мягко. Выглядит это так:
Возможно, щелчки были не багом, а фичей и давали более «футуристичный» звук, но мне больше нравится без них :)
Добавляем музыку
Мы передаём данные через звук. Почему бы не использовать для этого частоты нот? Я попробовал разные варианты, в итоге выбрал 16 нот, начиная с До первой октавы.
Если использовать более высокие ноты, то становиться менее комфортно ушам. А более низкие ноты хуже передаются из-за особенностей АЧХ динамиков и микрофонов. Также частоты низких нот ближе друг к другу, что ухудшает приём.
Получилась своего рода музыкально-частотная модуляция. Назовём её «Круп-модуляция» :)
Запускаем
Как же это звучит? Чтобы можно было попробовать прямо в браузере, я переписал передатчик с Круп-модуляцией с питона на js и сделал простенький интерфейс.
Пользуясь случаем, хочу передать привет:
Я использую utf-8, а значит кириллические символы и даже эмодзи тоже можно передавать. Посылки с ними получаются длиннее, так как на каждый такой символ приходится больше 1 байта.
Звучит чуть менее приятно, чем латиница, так как каждый кириллический символ содержит один и тот же байт адресации. Но все равно интересно :)
Можете попробовать любые фразы тут. (Продублирую в конце статьи)
А как же приёмник?
Это, конечно, весело — слушать рандомные звуки на основе текста, но передачей данных можно будет назвать только если сигнал будет приниматься, демодулироваться и декодироваться.
Я сделал прототип приёмника на питоне в качестве proof of concept. Вот, как он работает:
Видите, передача данных идет, как по нотам! Конечно, ни о каком продакшене сейчас речи не идёт. Тут нет синхронизации, помехоустойчивого кодирования и контроля целостности. Но если сообщество проявит интерес и подкинет пару вариантов практического применения, я могу реализовать перечисленный функционал и обернуть в нормальную библиотеку :)
Подводя итог
Это был интересный проект на пару вечеров с достаточно эффектным результатом. Такую передачу данных можно использовать, например, как «звуковой QR-code» — расшарить аккаунт с телефона на сайт и т.п.
Как вариант, с её помощью можно создавать мелодии для брендов. Вот, например, как звучит habr.
Все текущие наработки доступны на гитхабе — вы можете сами попробовать развить проект.
Дублирую ссылку на демку, работающую в браузере.
Спасибо, что дочитали! Надеюсь, вам было интересно.
Успехов!