本软件包提供了安全实时传输协议(SRTP)、通用安全转换(UST)以及配套加密内核的实现。SRTP API 文档见 include/srtp.h,库文件为 libsrtp2.a(编译后生成)。
本文档描述 libSRTP,即来自 Cisco Systems, Inc. 的开源安全 RTP 库。RTP 是实时传输协议(Real-time Transport Protocol),是 IETF 定义的用于传输电话、音频和视频等实时数据的标准,参见 RFC 3550。安全 RTP(SRTP)是 RTP 的一种轮廓(profile),用于为 RTP 数据提供机密性,并为 RTP 头部和载荷提供认证。SRTP 是 IETF 标准,定义于 RFC 3711,由 IETF 音视频传输(AVT)工作组制定。本库支持 SRTP 的全部强制特性,但不支持全部可选特性。更多详细信息请参见支持的特性一节。
本文档还用于生成 /doc/ 文件夹中的文档文件,其中可以创建更详细的 libSRTP API 及相关函数的参考手册(需要安装 doxygen)。参考材料由部分 C 头文件中嵌入的注释自动生成。文档按模块组织以提高清晰度,这些模块并不直接对应文件。底层加密内核提供了 libSRTP 的大部分基础功能,但由于其在幕后工作,因此大多没有文档说明。
[email protected] 用于新闻/公告/讨论的通用邮件列表。这是一个开放列表,注册请见 https://lists.packetizer.com/mailman/listinfo/libsrtp。
[email protected] 用于向 libsrtp 维护团队披露安全问题。这是一个封闭列表,但任何人都可以向其发送邮件。
libSRTP 按以下许可证分发,该许可证包含在源代码发行版中。此处将其转载于手册中,以防您从其他来源获取该库。
版权所有(c)2001-2017 Cisco Systems, Inc. 保留所有权利。
允许以源代码和二进制形式重新分发和使用,无论是否经过修改,前提是满足以下条件:
- 源代码的再分发必须保留上述版权声明、此条件列表和以下免责声明。
- 二进制形式的再分发必须在提供的文档和/或其他材料中复现上述版权声明、此条件列表和以下免责声明。
- 未经事先明确书面许可,不得使用 Cisco Systems, Inc. 的名称或其贡献者的名称来认可或推广从本软件衍生的产品。
本软件由版权所有者和贡献者“按原样”提供,不提供任何明示或暗示的担保,包括但不限于适销性和特定用途适用性的暗示担保。在任何情况下,版权所有者和贡献者均不对任何直接、间接、附带、特殊、惩戒性或后果性损害(包括但不限于采购替代商品或服务;使用、数据或利润的损失;或业务中断)承担责任,无论其原因如何,也不论是基于合同、严格责任还是侵权行为(包括疏忽或其他方式),即使已被告知此类损害的可能性。
libSRTP 提供保护 RTP 和 RTCP 的函数。RTP 数据包可以被加密和认证(使用 srtp_protect() 函数),从而转换为 SRTP 数据包。类似地,SRTP 数据包可以被解密并验证其认证信息(使用 srtp_unprotect() 函数),从而转换回 RTP 数据包。类似的函数可将安全性应用于 RTCP 数据包。
typedef srtp_stream_t 指向一个结构体,该结构体保存与 SRTP 流相关的所有状态,包括密钥、密码和消息认证函数的参数以及防重放数据。特定的 srtp_stream_t 保存保护特定 RTP 和 RTCP 流所需的信息。此数据类型有意保持不透明,以便更好地将 libSRTP API 与其实现分离。
在一个 SRTP 会话中,可以有多个流,每个流源自特定的发送方。每个源使用不同的流上下文来保护其发起的 RTP 和 RTCP 流。typedef 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 会话由一对目标传输地址定义,即一个网络地址加上一对用于 RTP 和 RTCP 的 UDP 端口。RTCP(RTP 控制协议)用于协调 RTP 会话中的参与者,例如提供从接收方到发送方的反馈。SRTP 会话 的定义类似;它只是使用 SRTP 轮廓的 RTP 会话。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 规范中描述的某些选项不受支持。这包括
用户应当注意,可能误用本库,从而导致其提供的安全级别不足。如果您正在使用本库实现某项功能,您需要阅读 RFC 3711 的安全注意事项一节。此外,务必阅读并理解许可证与免责声明一节中概述的条款。
本库还支持 RFC 7714 中描述的 AES-GCM 认证加密方法。
可以配置 libSRTP 将使用哪个第三方(例如 openssl/nss 等)加密后端进行构建。如果未设置第三方后端,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 的初始序列号;自版本 1.0.1 起,rdbx_estimate_index(...) 函数已变得更加智能,因此不再需要此技巧。
(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:
选项 | 描述
-------------------------------|--------------------
\-\-help \-h | 显示帮助
\-\-enable-debug-logging | 在所有模块中启用调试日志
\-\-enable-openssl | 启用 OpenSSL 加密引擎
\-\-enable-nss | 启用 NSS 加密引擎
\-\-enable-openssl-kdf | 启用 OpenSSL KDF 算法
\-\-enable-log-stdout | 启用输出到 stdout 的日志
\-\-with-openssl-dir | OpenSSL 安装位置
\-\-with-nss-dir | NSS 安装位置
\-\-with-log-file | 使用文件进行日志记录
默认情况下没有日志输出,可以使用配置选项启用日志,使其输出到 stdout 或指定文件。
此软件包已在以下平台上测试: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)。
--------------------------------------------------------------------------------