最近工作上需要理解srtp协议,学习协议最好的方式就是阅读RFC文档,但英文文档读起来有点费劲,网上也找不到对应的中文翻译,所以便决定把RFC3711翻译成中文,一来是逼迫自己读懂每一段每一句,二来希望对从事音视频开发的程序员有帮助。
rtp(实时传输协议)用于传输实时音视频数据;rtcp(实时传输控制协议)是rtp的配套协议,用于实时数据传输的监控和反馈、保证服务质量;srtp是rtp的profile,工作于rtp与传输层(例如udp)之间,为rtp提供数据加密、消息认证和重放保护,srtcp为rtcp提供类似功能。
1 序言
本文描述安全实时传输协议(SRTP),实时传输协议(RTP)的profile,它为RTP传输和RTP控制传输(RTCP)提供加密、消息认证、重放保护。
SRTP为RTP和RTCP流的加密、消息认证、重放保护提供一个框架。SRTP定义了一个加密变化的集合,并支持新的加密变化在未来被引入进来。同适合的key管理一道,为单播和多播RTP应用程序提供安全性。
SRTP可以实现高的吞吐和低的包膨胀,SRTP被证明能为异构环境(有无线混合)提供合适的保护。为获得这些特征,描述默认的变换,基于额外的流密文实现加密,基于带key的散列函数用于消息认证,和基于RTP顺序号的一个隐式的索引实现顺序化和同步,和为了SRTCP的索引号。
2 目标和特征
srtp的安全目标是为了
为rtp、rtcp的负载(payload)提供加密,保证机密性。
为rtp、rtcp整个包提供完整性保护。
为rtp、rtcp提供包重放保护。
上述安全服务是可选的、且相互独立,只有srtcp的完整性保护是必选的。
另外,功能上,协议的目标是:
支持升级新变化算法的框架
低带宽消耗,例如,框架支持rtp头部的高效压缩
并且,预定义变换支持:
低计算消耗
为支持节省带宽,限制包膨胀
独立于被RTP使用的底层传输、网络、和物理层,高容错丢包和乱序
这些特征确保srtp无论在有线还是无线网络环境下,都是rtp/rtcp的合适的安全保护方案。
2.1 特征
单独的master key,为srtp流和对应的srtcp流提供用于加密和完整性保护的key素材。这是通过一个key派生函数实现的,key派生函数从master key派生出session keys,用于各自的安全操作。
key派生可以被配置成周期性刷新session keys,限制每个session key产生的密文数,从而用于对抗对手的解密分析。
salting keys用于防范预计算和时间-空间置换攻击。
3 SRTP框架
srtp存在于rtp应用和网络传输层之间,在发送端,srtp拦截rtp包,并将它转换为srtp包;在接收端,srtp拦截srtp包,并将对应rtp包传递给rtp应用。
3.1 安全RTP
srtp包格式
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<+
|V=2|P|X| CC |M| PT | sequence number | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| timestamp | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| synchronization source (SSRC) identifier | |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ |
| contributing source (CSRC) identifiers | |
| .... | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| RTP extension (OPTIONAL) | |
+>+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| | payload ... | |
| | +-------------------------------+ |
| | | RTP padding | RTP pad count | |
+>+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+<+
| ~ SRTP MKI (OPTIONAL) ~ |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| : authentication tag (RECOMMENDED) : |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| |
+- Encrypted Portion* Authenticated Portion ---+
加密部分包括payload和padding部分(如果有),加密部分的大小>=未加密之前的rtp负载大小,如果用预加密变换算法的话,那加密前后大小相等。
MKI:master key标识符,可选,长度可配置,MKI由key management定义、产生(signaled)、使用,用于和/或加密特定包的session key将从master key派生,MKI不能标识srtp加密上下文,MKI被key management用于re-keying、标识加密上下文中的特定主键。
认证标签:推荐,长度可配置,消息认证包括rtp包头+加密部分数据,如果加密和认证都被应用,则先加密,然后对rtp包头和加密后的数据,再认证,接收端则遵循相反的顺序。认证标签也通过认证序列化隐式提供重放保护。
3.2 SRTP加密上下文
每个SRTP流都需要在发送端和接收端维护加密状态信息,该信息叫加密上下文。
SRTP使用2种类型的key:session key和master key。session key直接用于加密变换,包括负载加密和消息认证。master key是一个随机字符串,由key管理协议提供,session key通过安全的方式从master key推导生成。加密上下文中的master key和其他参数由srtp以外的key管理机制提供。
加密上下文中的参数分为变换独立参数和变化相关参数。
3.2.1 变换独立参数
加密上下文中的变换独立参数跟所采用的特定加密和认证变换无关,包括:
ROC,32位无符号回绕计数,记录16位rtp顺序号回绕(到达65535后自增重置为0)的次数,顺序号(seq)从rtp包头里提取,48位的rtp包索引通过公式获得:
i = 2^16 * ROC + SEQ
16位的顺序号s_l是接收端独有,可被当做接收到的rtp包的最高顺序号,因为消息认证被推荐使用,所以s_l应该被认证。
加密算法标识符,例如:密码和操作模式。
消息认证算法标识符。
重放列表,只有接收端才需要维护(当认证和重放保护被提供),包含最近接收并认证的消息索引。
MKI指示符(0或1),标识srtp、srtcp包中是否包含MKI。
如果MKI指示符为1,MKI字段的长度(以字节计),和(发送端)当前生效的MKI的实际值,MKI指示符和长度在上下文的整个生命周期应该保持固定不变。
master key,必须随机且保密。
针对每个master key,有一个用该master key处理过的srtp包的计数,本质上是为了安全考虑。
非负整数n_e(决定用于加密session key的长度)和n_a(决定用于消息认证session key的长度)。
另外,针对每个master key,srtp流可能使用以下相关值。
master salt,被用于session key的派生,当使用该值时,必须随机,但可公开,强烈建议使用master salt,空salt被当做“00...0”。
key派生率,key_derivation_rate,它是一个整数,取值{1,2,4,...,2^24}之一,如未指定,将被当做0。key派生率限定为必须是2的n次方,是为了简化key派生算法的实现。
一个MKI值。
srtcp默认应该跟srtp共享加密上下文,但不包括:
srtcp上下文不需要维护roc和s_l值,因为srtcp包会显式的携带rtcp索引。
srtcp需要维护独立的重放列表(如果提供重放保护的话)。
srtcp为master key维护单独的计数(哪怕master key跟srtp一样),该计数也是记录用该master key处理过了多少srtcp包。
注意,如果预定义变换(包括key派生)被采用,在特殊情况下,srtp和对应的srtcp可以共享master key,但必不可共享session key。
另外,一个rtp session中有多个srtp流,通过它们的同步源(位于rtp header中的ssrc)区分,它们共享大部分加密上下文参数。在这种情况下,普通的参数可以按以上描述的共享,但每个流还是要独立拥有重放列表和包计数,单独的srtp索引也必须独立维护。
上述参数的参数概要,预定义变换,默认值在p 5和8.2讲述。
3.2.2 变换相关参数
所有加密、认证、完整性和key派生参数在变换章节(Section 4)定义。密文(cipher)块大小、session keys、初始化向量(IV)信息的数据等是典型的此类参数。未来的srtp变换规范必须包括一段(如果有)去罗列其他用于变换等的加密上下文参数。
3.2.3 映射srtp包到加密上下文
一个rtp会话被定义为一对目的传输地址(一个网络地址+一对分别用于rtp和rtcp的端口),多媒体会话是rtp会话的集合。例如,一个特定多媒体会话可能包括一个音频rtp会话,一个视频rtp会话,和一个文本rtp会话。
一个加密上下文应该被唯一标识为三元上下文标识:
上下文ID =
其中目的网络地址和目的传输端口号携带在srtp包中。
如上所述,srtp和srtcp共享大部分加密上下文参数。因此,获取srtcp流的加密上下文参数可能意味着绑定对应srtp的加密上下文,该绑定由实现去完成,因为rtcp端口号不能直接通过rtp端口号推导出来。或者,key管理可以通过复制公共参数(比如master key),去提供独立的srtp上下文和srtcp上下文。后一种方法也使得srtp和srtcp可以使用不同的变换,如果需要的话。
找不到对应的有效上下文的包,必须被丢弃。
3.3 srtp包处理
以下处理步骤用于srtp包。Section 3.4描述srtcp包处理流程。
假设key管理已经做了加密上下文的初始化,发送端应该按以下步骤构建srtp包:
确定要使用哪个加密上下文,按照p 3.2.3所述。
按照p 3.3.1描述的那样,通过加密上下文中的ROC、最高顺序号,和RTP包中的顺序号,去确定srtp包索引。
确定master key和master salt。按照p 8.1描述,通过上一步中确定下来的包索引或者加密上下文中的当前MKI,去确定master key和master salt。
确定session key和session salt(如果session salt被用于变换),按照p 4.3所述,该步需使用加密上下文中的master key、master salt、key派生率、会话key长度和包索引(这些用到的信息通过步骤2和3确定)。
加密rtp包的payload产生包的密文数据部分,这一步使用加密上下文中加密算法标识符所指定的加密算法,session加密key和session salt(如果用到)和包索引(步骤2确定)。
如果MKI指示符为1,把MKI添加到packet尾部。
计算认证标签,按照p 4.2所述,该步骤使用了加密上下文中的ROC、认证算法标识,和第4步骤中的session认证key,并将认证标签添加到包尾。
如有必要,按照p3.3.1所述,使用步骤2确定下来的包索引,更新ROC。
接收端按以下步骤,去认证和解密srtp包。
确定要被使用的加密上下文。按照p 3.2.3。
执行p 3.3.1的算法去获得srtp包索引。该算法使用加密上下文中的ROC、最高顺序号和srtp包中的顺序号,如p 3.3.1所述。
确定master key和master salt。如果加密上下文中的MKI为1,使用srtp包中的MKI,否则使用上一步骤中的srtp索引(根据p 8.1)。
确定session key和session salt(如被用于变换)。按照p 4.3所述,使用加密上下文中的master key、master salt、key派生率、session key长度和srtp包索引(步骤2确定)。
对于消息认证和重放保护,首先判断该包是否重放包(通过重放列表和步骤2确定的srtp包索引判断),如果是重放包,则丢弃该包,并记录该事件。下一步,验证认证标签,使用步骤2中的ROC、加密上下文中的认证算法和session认证key,如果验证失败,则丢弃包,并记录该事件。
解密包的密文数据部分(参考p 4.1的ciphers)。使用加密上下文中的解密算法和session解密key和salt(如果需要),和srtp包索引(步骤2)。
更新加密上下文中的ROC和最高顺序号、s_l,该步使用步骤2确定的srtp包索引。如果提供了重放保护,则需要更新重放列表。
如果包中存在MKI、认证标签字段,则移除它们。
--未完待续
3.3.1 包索引确定和ROC、s_l更新
3.3.2 重放保护
3.4 安全rtcp
4 预定义加密变换
4.1 加密
4.1.1 AES-CM(计数模式)
4.1.2 AES-f8模式
4.1.2.1 f8关键流生成
4.1.2.2 f8 srtp iv 格式
4.1.2.3 f8 srtcp iv 格式
4.1.4 空加密
4.2 消息认证和完整性
4.2.1 HMAC-SHA1(基于散列的消息认证码-SHA1)
4.3 key派生
4.3.1 key派生算法
4.3.2 SRTCP key派生
4.3.4 AES-CM PRF
5 默认和强制实现变换
6 增加SRTP变换
7 逻辑依据
8 key管理考虑
9 安全考虑
10 与前向错误矫正机制的交互