
Библиотека для SRTP (Secure Realtime Transport Protocol)
Этот пакет предоставляет реализацию протокола Secure Real-time Transport Protocol (SRTP), универсального преобразования безопасности Universal Security Transform (UST) и поддерживающего криптографического ядра. API SRTP описан в include/srtp.h, а библиотека находится в libsrtp2.a (после компиляции).
В этом документе описывается libSRTP — библиотека Open Source Secure RTP от Cisco Systems, Inc. RTP — это протокол Real-time Transport Protocol, стандарт IETF для передачи данных в реальном времени, таких как телефония, аудио и видео, определённый в RFC 3550. Secure RTP (SRTP) — это профиль RTP, обеспечивающий конфиденциальность данных RTP и аутентификацию заголовка и полезной нагрузки RTP. SRTP является стандартом IETF, определённым в RFC 3711, и был разработан в рабочей группе IETF Audio/Video Transport (AVT). Эта библиотека поддерживает все обязательные функции SRTP, но не все необязательные. Более подробную информацию см. в разделе Поддерживаемые возможности.
Этот документ также используется для создания файлов документации в папке /doc/, где можно получить более подробный справочник по API libSRTP и связанным функциям (требуется установка doxygen). Справочные материалы создаются автоматически из комментариев, встроенных в некоторые заголовочные файлы C. Документация организована в модули для улучшения её читаемости. Эти модули не соответствуют напрямую файлам. Базовое криптографическое ядро обеспечивает большую часть основной функциональности libSRTP, но в основном не документировано, поскольку работает за кулисами.
[email protected] — общий список рассылки для новостей / объявлений / обсуждений. Это открытый список, для подписки см. https://lists.packetizer.com/mailman/listinfo/libsrtp.
[email protected] — для сообщения о проблемах безопасности команде сопровождения libsrtp. Это закрытый список, но отправлять сообщения может любой.
libSRTP распространяется под следующей лицензией, которая включена в дистрибутив исходного кода. Она воспроизведена в руководстве на случай, если вы получили библиотеку из другого источника.
Copyright (c) 2001-2017 Cisco Systems, Inc. Все права защищены.
Разрешается распространение и использование в исходной и двоичной формах, с изменениями или без, при условии соблюдения следующих требований:
- При распространении исходного кода необходимо сохранять вышеуказанное уведомление об авторских правах, этот список условий и следующий отказ от ответственности.
- При распространении в двоичной форме вышеуказанное уведомление об авторских правах, этот список условий и следующий отказ от ответственности должны воспроизводиться в документации и/или других материалах, поставляемых с дистрибутивом.
- Ни название Cisco Systems, Inc. ни имена её участников не могут использоваться для одобрения или продвижения продуктов, созданных на основе этого программного обеспечения, без предварительного письменного разрешения.
ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ ПРАВООБЛАДАТЕЛЯМИ И УЧАСТНИКАМИ «КАК ЕСТЬ», И ЛЮБЫЕ ЯВНЫЕ ИЛИ ПОДРАЗУМЕВАЕМЫЕ ГАРАНТИИ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ПОДРАЗУМЕВАЕМЫЕ ГАРАНТИИ КОММЕРЧЕСКОЙ ПРИГОДНОСТИ И ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЁННОЙ ЦЕЛИ, ОТКЛОНЯЮТСЯ. НИ ПРИ КАКИХ ОБСТОЯТЕЛЬСТВАХ ПРАВООБЛАДАТЕЛИ ИЛИ УЧАСТНИКИ НЕ НЕСУТ ОТВЕТСТВЕННОСТИ ЗА ЛЮБЫЕ ПРЯМЫЕ, КОСВЕННЫЕ, СЛУЧАЙНЫЕ, ОСОБЫЕ, ПОКАЗАТЕЛЬНЫЕ ИЛИ КОСВЕННЫЕ УБЫТКИ (ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ЗАТРАТЫ НА ПРИОБРЕТЕНИЕ ЗАМЕНЯЮЩИХ ТОВАРОВ ИЛИ УСЛУГ; ПОТЕРЮ ДАННЫХ, ДОХОДОВ ИЛИ ПРИБЫЛИ; ИЛИ ПРЕРЫВАНИЕ ДЕЯТЕЛЬНОСТИ), КАК БЫ ТО НИ БЫЛО ВЫЗВАНО, И ПО ЛЮБОЙ ТЕОРИИ ОТВЕТСТВЕННОСТИ, БУДЬ ТО ПО ДОГОВОРУ, СТРОГОЙ ОТВЕТСТВЕННОСТИ ИЛИ ДЕЛИКТУ (ВКЛЮЧАЯ НЕБРЕЖНОСТЬ ИЛИ ИНОЕ), ВОЗНИКШИЕ КАКИМ-ЛИБО ОБРАЗОМ ИЗ-ЗА ИСПОЛЬЗОВАНИЯ ЭТОГО ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ, ДАЖЕ ЕСЛИ БЫЛА СООБЩЕНА ВОЗМОЖНОСТЬ ТАКОГО УЩЕРБА.
libSRTP предоставляет функции для защиты RTP и RTCP. Пакеты RTP могут быть зашифрованы и аутентифицированы (с помощью функции srtp_protect()), превращая их в пакеты SRTP. Аналогичным образом пакеты SRTP могут быть расшифрованы и их аутентификация проверена (с помощью функции srtp_unprotect()), превращая их в пакеты RTP. Подобные функции обеспечивают безопасность пакетов RTCP.
Тип srtp_stream_t указывает на структуру, содержащую всё состояние, связанное с потоком SRTP, включая ключи и параметры для функций шифрования и аутентификации сообщений, а также данные защиты от повторного воспроизведения. Конкретный srtp_stream_t содержит информацию, необходимую для защиты конкретного потока RTP и RTCP. Этот тип данных намеренно непрозрачен, чтобы лучше отделить API libSRTP от его реализации.
В рамках сеанса SRTP может быть несколько потоков, каждый из которых исходит от конкретного отправителя. Каждый источник использует отдельный контекст потока для защиты исходящего потока RTP и RTCP. Тип srtp_t указывает на структуру, содержащую всё состояние, связанное с сеансом SRTP. С одним srtp_t может быть связано несколько контекстов потоков. Контекст потока не может существовать независимо от srtp_t, хотя, конечно, можно создать srtp_t, содержащий только один контекст потока. Устройство, участвующее в сеансе SRTP, должно иметь контекст потока для каждого источника в этом сеансе, чтобы обрабатывать данные, получаемые от каждого отправителя.
В libSRTP сеанс создаётся с помощью функции srtp_create(). Политика, реализуемая в сеансе, передаётся в эту функцию как непрозрачный дескриптор srtp_policy_t. Один дескриптор политики описывает политику одного потока. Для настройки нескольких потоков создайте сеанс и добавьте дополнительные политики с помощью srtp_stream_add().
Дескриптор политики настраивается с помощью функций srtp_policy_set_*. Как минимум, это включает выбор SSRC, выбор профиля и ключевой/солевой материал. Профиль задаёт параметры криптополитики RTP/RTCP, а селектор SSRC определяет, как и где применяется эта политика.
В этом разделе мы рассматриваем SRTP и вводим некоторые термины, используемые в libSRTP. Сеанс RTP определяется парой адресов транспорта назначения, то есть сетевым адресом и парой UDP-портов для RTP и RTCP. RTCP, протокол управления RTP, используется для координации между участниками сеанса RTP, например для обеспечения обратной связи от получателей к отправителям. Сеанс SRTP определяется аналогично; это просто сеанс RTP, для которого используется профиль SRTP. Сеанс SRTP состоит из трафика, отправляемого на адреса транспорта назначения SRTP или SRTCP. Каждый участник сеанса идентифицируется идентификатором источника синхронизации (SSRC). Некоторые участники могут не отправлять трафик SRTP; они называются приёмниками, даже если они отправляют трафик SRTCP, такой как отчёты приёмника.
RTP позволяет нескольким источникам отправлять трафик RTP и RTCP в одном сеансе. Идентификатор источника синхронизации (SSRC) используется для различения этих источников. В libSRTP мы называем трафик SRTP и SRTCP от конкретного источника потоком. Каждый поток имеет свой SSRC, порядковый номер, счётчик переполнения и другие данные. Конкретный выбор параметров, криптографических механизмов и ключей называется политикой. К каждому потоку в сеансе может применяться своя политика.
Одна политика может использоваться для всех потоков в данном сеансе, хотя случай, когда один ключ используется совместно несколькими потоками, требует осторожности. При совместном использовании ключей значения SSRC, идентифицирующие потоки, должны различаться. Это требование можно обеспечить, придерживаясь соглашения, согласно которому каждый ключ SRTP и SRTCP используется для шифрования только одним отправителем. Другими словами, ключ используется совместно только потоками, исходящими от конкретного устройства (разумеется, другим участникам SRTP понадобится этот ключ для расшифровки). libSRTP поддерживает это обеспечение, обнаруживая случай, когда ключ используется как для входящих, так и для исходящих данных.
Эта библиотека поддерживает все обязательные к реализации функции SRTP (как определено в RFC 3711). Некоторые из этих функций могут быть выбраны (или отключены) во время выполнения путём установки соответствующей политики с помощью дескриптора srtp_policy_t. Некоторые другие поведения протокола можно адаптировать, определив соответствующий обработчик событий для исключительных ситуаций; см. раздел SRTPevents в сгенерированной документации.
Некоторые параметры, описанные в спецификации SRTP, не поддерживаются. К ним относятся:
Пользователь должен знать, что возможно неправильное использование этой библиотеки, и в результате уровень безопасности, который она обеспечивает, может оказаться недостаточным. Если вы реализуете какую-либо функцию с использованием этой библиотеки, вам следует прочитать раздел Security Considerations (Вопросы безопасности) документа RFC 3711. Кроме того, важно прочитать и понять условия, изложенные в разделе Лицензия и отказ от ответственности.
Эта библиотека также поддерживает методы аутентифицированного шифрования AES-GCM, описанные в RFC 7714
Можно настроить, с каким сторонним криптографическим бэкендом (например, openssl/nss и т.д.) будет собран libSRTP. Если сторонний бэкенд не задан, libSRTP предоставляет внутреннюю реализацию AES и Sha1. Внутренняя реализация поддерживает только AES-128 и AES-256, поэтому для использования AES-192 или группы шифров AES-GCM необходимо настроить сторонний криптографический бэкенд. По этой и по причинам производительности настоятельно рекомендуется использовать сторонний криптографический бэкенд.
Функция srtp_protect() предполагает, что в буфере, содержащем
пакет rtp, выделено достаточно памяти, чтобы тег аутентификации
мог быть записан в конец этого пакета. Если это предположение
неверно, произойдёт повреждение памяти.
Автоматические тесты для криптографических функций предоставляются
через функции cipher_type_self_test() и auth_type_self_test().
Эти функции следует использовать для проверки каждого переноса
этого кода на новую платформу.
Защита от повторного воспроизведения встроена в криптографический движок, и для неё предоставляются тесты.
Эта реализация предоставляет вызовы для инициализации, защиты и снятия защиты пакетов RTP и делает как можно меньше предположений о том, как эти функции будут вызываться. Например, от вызывающего не ожидается предоставление пакетов по порядку (хотя если они вызываются с нарушением порядка более чем на 65k, синхронизация будет потеряна).
Порядковый номер в пакете rtp используется как младшие 16 бит
локального индекса пакета отправителя. Обратите внимание, что RTP начинает
свой порядковый номер со случайного места, а уровень SRTP просто переходит
вперёд к этому номеру при первом вызове. Более ранняя
версия этой библиотеки использовала начальные порядковые номера, которые
меньше 32 768; этот трюк больше не требуется, поскольку
функция rdbx_estimate_index(...) стала более интеллектуальной, начиная с
версии 1.0.1.
Окно защиты от повторного воспроизведения для (S)RTCP жёстко задано длиной 128 бит.
Чтобы установить libSRTP, загрузите последний релиз дистрибутива с https://github.com/cisco/libsrtp/releases. Вероятно, вам нужен самый свежий релиз. Распакуйте дистрибутив и извлеките исходные файлы; каталог, в который будут помещены исходные файлы, называется libsrtp-A-B-C, где A — номер версии, B — номер старшего релиза, а C — номер младшего релиза.
libSRTP использует утилиты GNU autoconf и make (BSD make не подойдёт; если на вашей платформе есть обе версии make, вы можете вызвать GNU make как gmake). В каталоге libsrtp выполните сценарий configure, а затем make:~~~.txt
./configure [ options ]
make
The configure script accepts the following options:
Option | Description
-------------------------------|--------------------
\-\-help \-h | Показать справку
\-\-enable-debug-logging | Включить отладочное журналирование во всех модулях
\-\-enable-openssl | Включить криптодвижок OpenSSL
\-\-enable-nss | Включить криптодвижок NSS
\-\-enable-openssl-kdf | Включить алгоритм KDF OpenSSL
\-\-enable-log-stdout | Включить вывод журнала в stdout
\-\-with-openssl-dir | Расположение установки OpenSSL
\-\-with-nss-dir | Расположение установки NSS
\-\-with-log-file | Использовать файл для журналирования
По умолчанию вывод журнала отсутствует; журналирование можно включить для вывода в stdout
или в указанный файл с помощью опций configure.
Этот пакет был протестирован на следующих платформах: Mac OS X
(powerpc-apple-darwin1.4), Cygwin (i686-pc-cygwin), Solaris
(sparc-sun-solaris2.6), RedHat Linux 7.1 и 9 (i686-pc-linux), а также
OpenBSD (sparc-unknown-openbsd2.7).
--------------------------------------------------------------------------------
<a name="changing-build-configuration"></a>
## Изменение конфигурации сборки
Чтобы собрать упомянутый выше сценарий `./configure`, libSRTP использует
инструментарий [automake](https://www.gnu.org/software/automake/). Поскольку
`./configure` собирается из `configure.in` с помощью automake, при внесении изменений
в то, как работает `./configure` (например, при добавлении новой зависимости библиотеки),
потребуется пересобрать `./configure` и зафиксировать обновлённую версию. Помимо
самого automake, также потребуется установить инструменты `pkgconfig`.
Например, в macOS:```
brew install automake pkgconfig
# Edit configure.in
autoremake -ivf
```
<a name="using-visual-studio"></a>
## Использование Visual Studio
В Windows можно использовать Visual Studio через CMake. CMake можно скачать здесь:
https://cmake.org/ . Чтобы создать файлы сборки Visual Studio, например, выполните
следующие команды:```
# Create build subdirectory
mkdir build
cd build
# Make project files
cmake .. -G "Visual Studio 15 2017"
# Or for 64 bit project files
cmake .. -G "Visual Studio 15 2017 Win64"
```
<a name="using-meson"></a>
## Использование Meson
На всех платформах, включая Windows, можно выполнить сборку с помощью [Meson](https://mesonbuild.com).
Инструкции по загрузке Meson находятся здесь: https://mesonbuild.com/Getting-meson.html
Для сборки с Meson можно сделать, например, следующее:```
# Setup the build subdirectory
meson setup --prefix=/path/to/prefix builddir
# Build the project
meson compile -C builddir
# Run tests
meson test -C builddir
# Optionally, install
meson install -C builddir
```
Чтобы собрать проект с помощью Visual Studio, выполните приведённые выше команды из командной строки Visual Studio
или запустите `vcvarsall.bat` с соответствующими аргументами в
командной строке.
Обратите внимание, что приведённые выше команды можно также заменить соответствующими `ninja`
целями: `ninja -C build`, `ninja -C build test`, `ninja -C build install`.
--------------------------------------------------------------------------------
<a name="applications"></a>
# Приложения
Несколько тестовых драйверов и простое переносимое приложение srtp
включены в подкаталог `test/`.
Тестовый драйвер | Тестируемая функция
--------- | -------
kernel_driver | криптографическое ядро (шифры, функции аутентификации, ГСЧ)
srtp_driver | тесты srtp в памяти (не используют сеть)
rdbx_driver | rdbx (расширенная база данных повторного воспроизведения)
roc_driver | функции расширенных порядковых номеров
replay_driver | база данных повторного воспроизведения
cipher_driver | шифры
auth_driver | хэш-функции
Приложение `rtpw` — это простое rtp-приложение, которое читает слова из
`/usr/dict/words` и затем отправляет их по одному с помощью [s]rtp.
Ручная настройка ключей srtp выполняется с помощью опции -k; автоматическое управление ключами
с помощью gdoi будет добавлено позже.
использование:~~~.txt
rtpw [[-d <debug>]* [-k|b <key> [-a][-e <key size>][-g]] [-s | -r] dest_ip dest_port] | [-l]
Либо должен быть выбран параметр -s (отправитель), либо -r (приёмник). Значения dest_ip, dest_port — это IP-адрес и UDP-порт, на которые будет отправлен словарь, соответственно.
Параметры:
Чтобы получить случайные 30-байтовые значения для использования в качестве пар ключ/соль, вы можете использовать следующую bash-функцию для форматирования вывода /dev/random (если это устройство доступно).~~~.txt
function randhex() {
cat /dev/random | od --read-bytes=32 --width=32 -x | awk '{ print $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16 }'
}
Ниже приведён пример SRTP-сеанса с использованием двух программ rtpw:~~~.txt
set k=c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451
[sh1]$ test/rtpw -s -k $k -e 128 -a 0.0.0.0 9999
Security services: confidentiality message authentication
set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451
setting SSRC to 2078917053
sending word: A
sending word: a
sending word: aa
sending word: aal
...
[sh2]$ test/rtpw -r -k $k -e 128 -a 0.0.0.0 9999
security services: confidentiality message authentication
set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451
19 octets received from SSRC 2078917053 word: A
19 octets received from SSRC 2078917053 word: a
20 octets received from SSRC 2078917053 word: aa
21 octets received from SSRC 2078917053 word: aal
...
В этом разделе приведён простой пример использования libSRTP. Здесь мы предполагаем,
что у нас есть функции get_rtp_packet() и send_srtp_packet(). Первая помещает RTP-пакет
в буфер и возвращает количество октетов, записанных в этот
буфер. Вторая отправляет RTP-пакет из буфера, принимая его
длину в качестве второго аргумента.~~~.c
srtp_t session;
srtp_policy_t policy;
// Set key/salt to predetermined values. uint8_t master_key[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; uint8_t master_salt[14] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D};
// Initialize libSRTP. srtp_init();
// Create and configure an opaque policy handle. srtp_policy_create(&policy); srtp_policy_set_ssrc(policy, (srtp_ssrc_t){ssrc_any_outbound, 0}); srtp_policy_set_profile(policy, srtp_profile_aes128_cm_sha1_80); srtp_policy_add_key(policy, master_key, sizeof(master_key), master_salt, sizeof(master_salt), NULL, 0);
// Allocate and initialize the SRTP session. srtp_create(&session, policy);
srtp_policy_destroy(policy);
// Main loop: get RTP packets, send SRTP packets. while (1) { char rtp_buffer[2048]; size_t rtp_len; char srtp_buffer[2048]; size_t srtp_len = sizeof(srtp_buffer);
rtp_len = get_rtp_packet(rtp_buffer); srtp_protect(session, rtp_buffer, rtp_len, srtp_buffer, &srtp_len); send_srtp_packet(srtp_buffer, srtp_len); }
srtp_dealloc(session); srtp_shutdown();
<a name="credits"></a>
# Благодарности
Оригинальная реализация и документация libSRTP были написаны
Дэвидом Макгрю из Cisco Systems, Inc. с целью содействия использованию,
пониманию и интероперабельности Secure RTP. Майкл Джеррис
добавил поддержку сборки в среде MSVC. Андрис Павенис
внёс множество важных исправлений. Брайан Уэст внёс изменения,
обеспечивающие динамическую компоновку. Ив Шуманн сообщил об ошибках
в документации. Рэнделл Джесап предоставил рабочую реализацию SRTCP
и другие исправления. Стив Андервуд внёс изменения для обеспечения
переносимости на x86_64. Мы также благодарим Фредрика Тулина, Брайана
Вайса, Марка Баугера, Джеффа Чана, Билла Саймона, Дугласа Смита, Билла
Мэя, Ричарда Пристли, Джо Тардо и других за вклад, комментарии и исправления.
Этот справочный материал, где применимо, в настоящей документации был
сгенерирован с помощью утилиты doxygen для автоматического документирования исходного кода.
Авторские права 2001-2005 принадлежат Дэвиду А. Макгрю, Cisco Systems, Inc.
--------------------------------------------------------------------------------
<a name="references"></a>
# Ссылки
Ссылки по SRTP и ICM
Сентябрь 2005 г.
Secure RTP определён в [RFC 3711](https://tools.ietf.org/html/rfc3711).
Определение режима счётчика приведено в [разделе 4.1.1](https://tools.ietf.org/html/rfc3711#section-4.1.1).
SHA-1 определён в [FIPS PUB 180-4](http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
HMAC определён в [RFC 2104](https://tools.ietf.org/html/rfc2104),
а тестовые векторы HMAC-SHA1 доступны
в [RFC 2202](https://tools.ietf.org/html/rfc2202#section-3).
Использование AES-GCM в SRTP определено в [RFC 7714](https://tools.ietf.org/html/rfc7714).
| Параметр | Описание |
|---|
| -s | (S)RTP-отправитель — заставляет приложение отправлять слова |
| -r | (S)RTP-приём — заставляет приложение получать слова |
| -k | используйте главный ключ SRTP , где ключ задан в шестнадцатеричном виде (без ведущего «0x») |
| -b | то же, что и -k, но с ключом в кодировке base64 |
| -e | шифрование/дешифрование (для конфиденциальности данных) (также требует использования параметра -k) (для keysize используйте 128, 192 или 256) |
| -g | использовать режим AES-GCM (должен использоваться с -e) |
| -a | аутентификация сообщений (также требует использования параметра -k) |
| -l | вывести список доступных модулей отладки |
| -d | включить отладку для модуля |