суббота, 4 августа 2012 г.

Проблема организации голосовых конференций в системах защищенной связи.


В большинстве распространенных VoIP решений трафик пропускается через сервер и шифрование осуществляется от клиента до сервера, далее присутствует на сервере в открытом виде и передается на другого клиента. Или же шифрование отсутствует вовсе.

При такой архитектуре сервер идеальное место для организации конференции. Работа сервера состоит в простой пересылке всех пакетов, приходящих от подключенных к конференции клиентов на других участников конференции, а для речевых пакетов, еще микширование голосовых пакетов от всех участников на сервере. С другой стороны сервер становится идеальным место для перехвата.

Политика сервиса Cryptia.com, состоит в том, что мы не стремимся хранить у себя конфиденциальные данные клиентов (или иметь к ней доступ). Все соединения между клиентами используют сквозное шифрование от клиента до клиента, без возможности расшифровки на сервере, а в 90% случаев они и проходят от клиента до клиента напрямую, минуя наши сервера.  Однако это с другой стороны делает невозможным организацию конференций на серверах, используя описанную выше технологию.

Описанное противоречие и есть причина того, что в сервисе Cryptia до сих пор не реализована функция конференции.

Для решения проблемы рассматривался вариант использования схемы согласования сеансового ключа по алгоритму Диффи-Хеллмана  для большого количества клиентов (> 2).  В этом случае сервер не расшифровывает голосовые пакеты и не может микшировать звук от разных клиентов, а только пересылает зашифрованные пакеты между клиентами. Клиент сам смешивает голосовой трафик на своем компьютере, но входящий трафик каждого участника конференции возрастает пропорционально количеству участников. Например, если в конференции участвуют 4 человека, то сервер будет пересылать на каждого участника пакеты от 3-х других и входящий трафик КАЖДОГО участника возрастет в 3 раза (относительно простого голосового сеанса).  Исходящий трафик останется без изменений. Возросший в 3 раза голосовой трафик может привести к тому, что один из клиентов может просто перестать работать.

Кроме того, для формирования сеансового ключа для всех участников конференции, требуется, чтобы все имели цифровые подписи друг друга. А как быть, если я хочу организовать конференцию с двумя людьми, которые пока не знакомы между собой, и соответственно, не имеют сертификатов друг друга для цифровой подписи?



Мы приняли компромиссное решение:
За функционирование конференции отвечает инициатор. Его клиентская программа выполняет роль  сервера конференции. Инициатор имеет защищенное соединение с каждым из участников  и расшифровывает пакеты, смешивает голосовые потоки и пересылает их другим.
Проблема трафика решается так: Трафик инициатора конференции возрастает пропорционально количеству участников, соответственно инициатор должен находиться в точке с хорошим Интернет каналом (не телефон с 3G). У остальных участников трафик не возрастает.  Проблема с обменом ключами в этом случае также решается – дополнительный обмен не требуется. Инициатор конференции расшифровывает все клиентские пакеты и пересылает их другим участникам. Разумеется, инициатор имеет возможность все видеть и, возможно, регистрировать, но он эту возможность имел и так (как и любой участник этой самой конференции).

Этот функционал будет включен в один из следующих релизов клиентской части продукта Cryptia.

OpenSSL и Qt.


OpenSSL сейчас является стандартом де-факто в области криптографии и используется повсеместно.

Во всех Linux, FreeBSD и Meego– при помощи библиотеки OpenSsl осуществляется все, что касается SSL соединений. В Mac OS X до 10.6 OpenSsl являлся единственным провайдером криптографических функций для SSL, а начиная с 10.7, появился новый провайдер, который, вероятно, использует только Apple. OpenSsl продолжает оставаться в MacOS X.  В Symbian OpenSsl присутствует во всех современных телефонах, однако, присутствует также и свой старый API для Symbian для поддержки старых приложений.

В процессе работы над клиентской и серверной частями сервиса cryptia.com было обнаружено, что в большинстве имеющихся на рынке unix based OS, собранный по умолчанию OpenSSL имеет умышленно вставленное ограничение на использование DSA ключей с длиной более 1024 бит.

Это обнаружено нами во ВСЕХ !!! имеющихся на рынке MacOS X, до 10.7.4. включительно, во всех Meego, в Symbian OS, во всех Android.
FreeBSD по умолчанию ставится тоже с пробитым OpenSSL, однако в портах лежит версия с официального сайта. Касательно репозитариев Linux: бывает по разному, но в большинстве дистрибутивов лежит версия с ослабленной защитой. В случае с сервисом Cryptia.com это проявляется в том, что клиентские сертификаты подписанные сервером (ключом DSA 2048 бит) не проходят верификацию в клиенте. Функция API EVP_VerifyFinal и EVP_SignFinal возвращает код ошибки («подпись не верна»).


У Вас на компьютере может стоять нормальный OpenSSL, однако при очередном обновлении OS из репозитария, в операционную систему, скорее всего, будет установлен  «правильный» OpenSSL и все программы начнут использовать его.



Как с этим бороться? «Таблетка».

Качать исходник OpenSSL с официального сайта openssl.org, который хостится в Германии и собирать его самому. Инструкция по сборке зависит от платформы, и для Desktop версии, как правило, не является проблемой.  Проблемой является избавиться в программе от зависимости Qt от OpenSsl в системе.

Замечания по грамотному использованию «Таблетки».

Qt библиотеки (OpenSSL использует только QtNetwork), как правило собираются с поддержкой динамической загрузки OpenSSL, хотя можно собрать и со статической линковкой OpenSSL.

Проблема в том, что в большинстве Linux дистрибутивов как-то собранные библиотеки Qt уже стоят (на Qt написана KDE). Также Qt уже установлена в последних телефонах с Symbian и Meego.  Требовать от пользователя поставить свой Qt или обновить его автоматически в программе установки дело очень рискованное – у пользователя могут «поломаться» уже установленные и работающие программы.

Почти во всех OS невозможно подгрузить в адресное пространство процесса две библиотеки с одинаковыми именами и одинаковым набором экспортируемых функций.

Если вы используете свою динамически загружаемую библиотеку OpenSsl, случайное обращение к QSslCertificates (Например, для того чтобы получить список корневых сертификатов встроенных в OS) приведет к тому что QtNetwork, попытается загрузить библиотеку OpenSsl, как правило из OS, а не вашу, потому что о вашей QtNetwork ничего не знает.

Вариант со статической линковкой своего Qt и openSsl  в программе, нравится не очень по следующим причинам:
  1. Как правило библиотеки Qt, по крайней мере в Linux, Symbian и Meego уже загружены каким-нибудь процессом в память и второй раз не загружаются, а вместо этого только выставляется отображение RO сегментов на память процесса и инициализация RW сегментов. Если статически слинковать весь Qt в программу, то программа «опухает» примерно на 10-15 MB, и запускается существенно дольше.
  2. В мобильных платформах ориентированных на Qt (Symbian, Meego (возможно BB10) ), тяжело пересобирать Qt статически.

По этой причине в клиентской программе Cryptia мы отказались от использования встроенной в Qt поддержки openssl. Для этого надо отказаться от использования всех классов начинающихся с QSsl (QSslSocket, QSslCertificate …). Все эти классы заменены своими. Для того чтобы случайно не «просочилось» где-нибудь в кусках старого кода использование этих классов, мы пересобрали у себя Qt c отключенной поддержкой OpenSsl. В этом случае компилятор будет ругаться при попытке использования в программе классов с QSsl  В своих классах мы используем вызовы своего OpenSSL, который статически линкуем к программе.

Таким образом, программа получается независимой от варианта сборки Qt, который она использует, а также от того, какой OpenSsl установлен у пользователя с одной стороны, а с другой – Qt все-таки динамически линкуется с программой и программа быстрее стартует на десктоп-платформах и просто работает на мобильных.


Ahtung. Пользователям программного обеспечения, которое использует библиотеку QCA.


QCA (Qt Cryptographic Architecture )  задумывался авторами, как кросс-платформенная библиотека надстройка над Qt, для функций шифрования.  Создавалась в те времена, когда в самой Qt функции шифрования не были встроены. 

Website: http://delta.affinix.com/qca/

После того как в самой Qt появились классы QSslSocket, QSslCertificates и.т.д.  разработка библиотеки была брошена авторами, однако многие продолжают ее использовать, например PSI. Кроме того последняя версия QCA (и плагина к ней для OpenSSL, датированного 2002 г. ) лежит во многих репозитариях Linux. Собственно всей криптография занимается OpenSSL, а QCA (с плагином для OpenSSL) выполняет роль прокладки между OpenSSL и Qt.  Криптографические функции в OpenSSL реализованы очень хорошо, однако требуют их грамотного использования, чем QCA похвастаться не может.

В частности OpenSSL требует грамотной инициализации пула случайных чисел (PRND)

А вот как инициализируется пул случайных чисел в QCA.

      srand(time(NULL));
      char buf[128];
      for(int n = 0; n < 128; ++n) buf[n] = rand();
      RAND_seed(buf, 128);

Как видно для инициализации используется «родная» функция rand() из библиотеки C, которая возвращает псевдослучайную последовательность чисел от 0 до 32767, а инициализируется генератор при помощи стандартной функции time, которая возвращает текущее время в виде количества секунд от 1 января 1970г. Фактически для взлома требуется небольшой перебор возможных значений времени в секундах от старта программы (порядка 12 бит.)

пятница, 20 июля 2012 г.

Передача речи через IP сети. Эффективность использования полосы.

Теоретические основы

Для передачи речи через IP сеть, оцифрованные звуковые данные от микрофона разбиваются на порции определенного размера, передаются через сеть IP на принимающую сторону, а на принимающей стороне собираются обратно и воспроизводятся в наушники.  Если оцифровывать речь с частотой 8000 kHz (телефонное качество), то мы будем иметь поток 8000 отсчетов/ сек * 16 бит / отсчет = 128 кбит/сек.
Желательно такой поток сжимать перед передачей по IP и декомпрессировать на принимающей стороне. Для сжатия желательно использовать вокодерные алгоритмы сжатия речи, так как:
  • Для восприятия речи не обязательно сжатие без потерь
  • Вокодерные алгоритмы имеют фунцию «восстановление после потери пакета»


Для VOIP приложений, как правило, используется UDP по следующим причинам:
  1. Гарантия доставки пакета, не столь принципиальна для речи. Опыты показывают, что если теряется до 10% пакетов, качество речи страдает незначительно. Гораздо важнее минимальная задержка.
  2. “Большой” размер заголовка съедает значительную часть полосы пропускания канала связи см. Пример ниже.


На стороне получателя поступающие данные буферизируются перед тем, как будут отправлены на звуковую плату. Этим занимается так называемый Jitter буфер. Jitter буфер придерживает пакеты на некоторое время, для того чтобы не возникало ситуации, когда в звуковую карту нечего отправить, из-за того, что пакет запаздывает. Размер задержки Jitter буфер адаптивно корректирует исходя из статистики поступления пакетов.

Пример:

Размер заголовка в UDP/IPv4 – 28 байт

Речь для передачи сжимается алгоритмом сжатия до 8000 bit/sec. Размер одного кадра 20 мсек. В одном пакете передается один кадр, для минимизации задержки.
Таким образом мы имеем 20 байт/кадр и 50 кадров (пакетов) /сек. Это только полезные данные без заголовков.

С учетом заголовков имеем:

Для UDP:
(28 байт заголовка + 20 байт данных) * 50 кадров/сек = 2400 байт/сек = 19200 бит/сек

В случае RTP поверх UDP:
(28 байт заголовка  UDP + 16 байт заголовка RTP + 20 байт данных) * 50 кадров/сек = 3200 байт/сек = 25600 бит/сек


Эффективность использования  = скорость полезных данных / скорость полных данных
Для UDP:       ŋ  = 8000 / 19200 = 41%.
Для RTP поверх UDP:         ŋ  = 8000 / 25600 = 31%.


Реализация в клиенте Cryptia.

Звуковые данные оцифровываются с частотой 8 kHz и обрабатываются алгоритмом сжатия речи Speex с длиной кадра 20 мсек, который поддерживает несколько режимов сжатия.  Разумеется, чем выше битрейт, тем выше качество речи. Поддерживается также переменный битрейт, в котором  алгоритм определяет сам какой из режимов нужно использовать для сжатия каждого речевого кадра, исходя из входных данных. Алгоритм уходит в режимы с меньшим битрейтом в случаях пауз между словами, а также в некоторых других случаях, когда высший режим не дает преимуществ перед низшим (например, длинные гласные в словах). Использование переменного битрейта позволяет сократить трафик примерно на 30% даже в случае кодирования звукового потока с непрерывной речью, а учитывая то, что разговор двух людей это на 99% полудуплексное общение (один говорит – другой слушает, потом наоборот) то использование переменного битрейта сокращает трафик почти в 2 раза. В случае переменного битрейта можно ограничить самый старший режим, который алгоритм может использовать, тогда он будет кодировать звуковые кадры используя этот режим или меньше.

Звуковые кадры могут упаковываться в пакеты UDP по 1,2,4 или 8 звуковых кадров в пакете. Таким образом, минимально возможная алгоритмическая задержка речи составляет 20, 40, 80 или 160 мсек соответственно.  Реально, с учетом Jitter буфера, существенно больше. 

В приведенной ниже таблице представлены реальные битрейты (с учетом UDP заголовков и заголовков протокола) при использовании различных режимов speex для сжатия речи, а также эффективность использования канала при выбранном режиме (ŋ)



Режим 0

2150 бит/сек
Режим 1

3950 бит/сек
Режим 2

5950 бит/сек
Режим 3

8000 бит/сек
Режим 5

11000 бит/сек
Режим 7

15000 бит/сек
Режим 9

18200 бит/сек
Режим 10

24600 бит/сек
1 Кадр / пакет
14400
ŋ = 15%
16000
ŋ  = 25%
18000
ŋ  = 33%
20000
ŋ  = 40%
23200
ŋ  = 47%
27200
ŋ  = 55%
30400
ŋ  = 60%
36800
ŋ  = 67%
2 Кадра / пакет
8200
ŋ  = 26%
10000
ŋ  = 40%
12000
ŋ  = 50%
14000
ŋ  = 57%
17000
ŋ  = 65%
19600
ŋ  = 72%
24200
ŋ  = 75%
30600
ŋ  = 80%
4 Кадра / пакет
5200
ŋ  = 41%
7000
ŋ  = 57%
9000
ŋ  = 66%
11000
ŋ  = 73%
14000
ŋ  =79 %
18000
ŋ  = 83%
21200
ŋ  = 86%
27600
ŋ  = 89%
8 Кадров / пакет
3650
ŋ  = 58%
5450
ŋ  = 72%
7450
ŋ  = 80%
9500
ŋ  = 84%
12500
ŋ  = 88%
16500
ŋ  = 91%
19700
ŋ  = 92%
26100
ŋ  = 94%


Каждый из пользователей, участвующих в разговоре, может в своем клиенте ограничить максимальную скорость передачи и приема данных (по умолчанию ограничений 36800 бит/сек, что фактически означает отсутствие ограничений полосы).  На этапе установления соединения клиенты договариваются между собой о том, кто с какой скоростью будет передавать речевые данные, а также предпочтения по получению звуковых данных. Этот параметр вынесен в настройки, поскольку он субъективен: одним пользователям комфортнее общаться, когда задержка минимальная в ущерб качеству речи, другим комфортнее общаться с наилучшим качеством речи, не обращая внимания на задержку. Существует еще режим, названный «оптимальный», который является разумным (по мнению авторов) компромиссом между качеством речи и задержкой.

Например если в клиенте А установлено ограничение на передачу на 20000 бит/сек, а в Клиенте B установлено ограничение на прием на 17000 бит/сек, то передача в направлении от Клиента А к клиенту B  будет осуществляться со скоростью не более 17000 бит/сек.  Т.е. передатчик может использовать только режимы отмеченные зеленым цветом.  (см. Таблицу ниже).  


Режим 0

2150 бит/сек
Режим 1

3950 бит/сек
Режим 2

5950 бит/сек
Режим 3

8000 бит/сек
Режим 5

11000 бит/сек
Режим 7

15000 бит/сек
Режим 9

18200 бит/сек
Режим 10

24600 бит/сек
1 Кадр / пакет
14400
16000
18000
20000
23200
27200
30400
36800
2 Кадра / пакет
8200
10000
12000
14000
17000
19600
24200
30600
4 Кадра / пакет
5200
7000
9000
11000
14000
18000
21200
27600
8 Кадров / пакет
3650
5450
7450
9500
12500
16500
19700
26100


В случае если получатель предпочитает получать звуковые данные с минимальной задержкой, то будет выбран режим 1 (3950 бит/сек) и упаковка по 1 кадру на пакет.
Если получатель предпочитает получать звук наилучшего качества, с большей задержкой, то будет выбран режим 7 (15000 бит/сек)  и упаковка по 8 кадров / пакет.
В оптимальном режиме будет выбран режим 5 (11000 бит/сек) и упаковка по 2 кадра в пакете.

Использование Режима 0 (2150 бит/сек) запрещено из-за того что качество речи при этом неудовлетворительное, однако алгоритм Speex может переходить в этот режим в случае использования переменного битрейта в паузах и.т.п.

Пользователь может запретить использование определенных режимов speex для передачи и приема. Реально это используется для запрета использования переменного битрейта передающей стороной.

Протокол RTP в Cryptia не используется, по причине непомерно большого заголовка (16 байт). Заголовок протокола для передачи речи в Cryptia составляет всего 2 байта и представляет собой просто порядковый номер пакета.

Существует мнение о том, что переменный битрейт ослабляет криптозащиту зашифрованных VoIP потоков.  http://www.computerra.ru/think/kiwi/362826/


Группа исследователей из американского Университета Джонса Хопкинса (Johns Hopkins University) продемонстрировала, что сжатие с переменным битрейтом очень сильно ослабляет криптозащиту зашифрованных VoIP-потоков. Ученые показали, что достаточно измерять размер пакетов, даже не прибегая к их декодированию, чтобы с высокой точностью выявлять слова и фразы. Программа анализа, разработанная авторами, пока не может восстановить весь разговор целиком, однако позволяет отыскивать конкретные словосочетания в зашифрованном потоке.
Алгоритм программы с помощью фонетического словаря разбивает искомую фразу на фонемы. Затем фраза составляется из звуков, взятых из библиотеки образцов, а результат преобразуется в набор VoIP-пакетов. Полученная структура дает общее представление о том, как фраза может выглядеть в реальном VoIP-потоке. И когда нечто похожее по структуре выявляется в реальном сеансе IP-телефонии, программа тут же оповещает перехватчика о находке.
При тестовых испытаниях с перехватом реальной зашифрованной передачи программа верно выявляла и декодировала искомые фразы примерно в половине случаев. Результат, ясное дело, не очень впечатляющий, однако аккуратность метода подскакивала до 90%, если для поиска задавались длинные и сложные слова. Иначе говоря, эффективность подобной атаки намного выше, если перехватывается разговор профессионалов, насыщенный жаргонизмами. Как показывает анализ, в разговорах на профессиональном "диалекте" обычно много слов, которые сцепляются в длинные и относительно предсказуемые фразы. Что же касается неформальных звонков, то там набор выражений случаен, а потому значительно хуже поддается аналитическому декодированию. Впрочем, досужий треп обывателей шпионам неинтересен.
Самым простым решением проблемы могло бы стать разбиение речевого потока на пакеты равной длины, однако это неизбежно ухудшит степень сжатия. Что в очередной раз, увы, подтверждает давно известную истину: эффективность и безопасность - вещи практически несовместимые.


По этой причине использование переменного битрейта по умолчанию запрещено. Вы можете вручную активировать его при помощи настроек программы.
По нашему мнению серьезность проблемы сильно преувеличена.  Если использовать переменный битрейт одновременно с ограничением верхней скорости, то эффективность такой атаки существенно упадет от заявленных 50%. Например, если ограничить верхнюю скорость потока 9400 бит/сек, то алгоритм будет работать выбирая из 3 возможных скоростей 5950, 3950 и 2150 бит/сек.  Кроме того, в этом случае будет установлена упаковка голосовых кадров по 4 кадра в пакете. Эффективность такой атаки упадет еще на порядок. Мы сильно сомневаемся в целесообразности атаки, в случае успеха которой атакующая сторона сможет сказать: «с вероятностью 5 % в зашифрованном разговоре присутствует фраза: ….  » .
Если тем не менее вас волнует эта проблема, то для отключения переменного битрейта вам достаточно просто снять галочку напротив пункта «Разрешить переменный битрейт» в окне «Настройки/Качество Речи», Возможно, что находясь в роуминге, вы не захотите платить в 4 раза больше за качественную передачу речи. Кроме того, не всегда имеется достаточно быстрый канал связи, например, в случае подключения через общедоступную точку доступа WI-FI или сеть EDGE.  Возможно, что с ограниченной скоростью передачи, приема и переменным битрейтом поговорить удастся, а без этого нет.