介绍
SRTP(Secure Real-time Transport Protocol)是对 RTP 协议的扩展,旨在提供数据加密、消息认证、完整性保护和重放保护等安全机制。SRTP使用对称加密算法对 RTP/RTCP 数据包的有效载荷进行加密保护,使用签名算法提供完整性保护和消息认证。
SRTP的安全目标
- 对 RTP/RTCP 的负载(payload)进行加密保护、保证机密性。
- 对 RTP/RTCP 的整个包提供完整性保护和消息认证。
- 为 RTP/RTCP 提供重放保护。
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 ---+
SRTP MKI (OPTIONAL) 和 authentication tag (RECOMMENDED) 是 SRTP 定义的唯一不在RTP中的字段。
- SRTP MKI (OPTIONAL):可选。MKI由密钥管理定义、发送信号和使用。MKI用于标识主密钥。MKI不受完整性保护,因为这不提供任何额外保护。
- Authentication tag(认证标签):推荐。认证标签用于携带消息认证数据。SRTP数据包的认证部分由RTP标头和SRTP数据包的加密部分组成。身份验证标签提高对RTP头和有效载荷的身份验证,并通过对序列号进行身份验证来间接提供重放保护。
其他字段同 RTP,只不过 SRTP 中的 RTP 的 Payload 为密文。
加密上下文
每个 SRTP 流都需要发送方和接收方维护加密状态信息。该信息被称为 加密上下文 。
每个参与者的 RTP 会话由一对目标传输地址 <ip, port> 定义。
RTP 会话中的 SRTP 流由 SSRC 标识,同一个RTP会话中的SRTP 流共享大多数加密上下文参数。但仍然必须为每个 SRTP流(SSRC)维护单独的重放列表和数据包计数器。此外必须保持单独的 SRTP 索引。
因此,加密上下文由三元组唯一标识,即 context id = <SSRC, ip, port>,密钥管理根据 context id 返回 Cryptographic Contexts 。
与加密变换无关的参数
- 一个32位的无符号的翻转计数器(ROC(rollover counter)):用于记录 16位 的 RTP SN (Sequence Number)经历了多少次重置为 0 (溢出后(超过65535后翻转))。
- SRTP Packet 的 索引:index = 2^16 * ROC + SEQ,其中 SEQ 是当前RTP Packet的Sequence Number。
- 一个16位的序列号 s_1 : 仅用于接收者维护,可认为是接收到的最高的 RTP 序列号。
- 加密算法的标识符:表示使用何种加密算法。
- 消息认证算法的标识符:表示使用何种消息认证算法。
- 重放列表:仅由接收者维护,包含最近接收和已验证的SRTP数据包的索引,用于防重放攻击。
- MKI指示符(0/1):用于标识一个 MKI 是否存在 SRTP Packet 中。
- Master key:主密钥
- Master key 计数器:每一个 Master Key 一个计数器,统计当前 master key 处理过的SRTP包。
- 非负整数 n_e : 用于加密的 session key 的长度。
- 非负整数 n_a : 用于消息认证的 session key 的长度。
- Master salt :用于 session key 的密钥派生,加点盐使得安全性更高。
- key_derivation_rate:密钥推导率,用于密钥派生的一个参数,集合 {1,2,4,...,2^24} 中的整数(2的幂的约束简化了会话密钥的推导实现)。
- MKI值
- <From, To>二元组,指定 master key 的生命周期,<From, To> 是一个 MKI 的替代方案。
默认情况下,SRTCP与SRTP共享加密上下文,除了:
- SRTCP 不需要 ROC 和 s_1,因为 SRTCP 已明确携带 RTCP 索引。
- SRTCP 使用独立的重放列表。
- SRTCP 使用独立的 master key 计数器,用于统计已发送的
此外,可能存在以下情况:给定的RTP会话中的几个 SRTP 流,由它们的标识同步源(SSRC,有别于CSRC,SSRC是RTP头的一部分)共享大多数加密上下文参数(包括master key)。当然,SRTP索引、重放列表和数据包计数器仍然必须分开独立维护。
与加密变换相关的参数:
- BLOCK_CIPHER_MODE:表示使用的密码(例如:AES)及其运作模式(例如:AES-计数器模式、AES-f8模式)。
- n_b:块密码的位大小
- k_e:session key
- n_e:k_e 的位长
- k_s:session salt key
- n_s:k_s 的位长
- SRTP_PREFIX_LENGTH:密钥流前缀的字节(8bit)长度,一个非负整数,由消息认证码指定正在使用。
SRTP Packet Processing
假设加密上下文的初始化已通过密钥管理进行。
发送方加密
-
根据 <SSRC, ip, port> 获取加密上下文
-
使用翻转计数器、加密上下文中的最高序列号和 RTP 数据包中的序列号:确定 SRTP 数据包的索引
-
确定master key 和 master salt。 这是使用在上一步中确定的索引或加密上下文中的当前 MKI 完成的.
-
使用 索引,master key,master salt 确定 session key 和 session salt 和 session authentication key
-
使用 加密算法(可能会用到ssrc),session key ,session salt(可选)加密 RTP 负载以生成数据包的加密部分。
-
如果 MKI 指示符设置为 1,则将 MKI 附加到数据包中。
-
使用 ROC, the authentication algorithm indicated in the cryptographic context, and the session authentication key 计算数据包认证部分的认证标签,
-
更新 ROC
接收方解密
-
根据 <SSRC, ip, port> 获取加密上下文
-
使用翻转计数器、加密上下文中的最高序列号和 RTP 数据包中的序列号:确定 SRTP 数据包的索引
-
确定master key 和 master salt。如果上下文中的 MKI 指示符设置为 1,则使用 SRTP 数据包中的 MKI,否则使用第2步中的索引
-
确定 session key 和 session salt 和 session authentication key
-
对于消息认证和重放保护,首先检查数据包是否已经被重放(3.3.2节),使用重放列表和步骤2中确定的索引。如果判断数据包被重放,则必须丢弃该数据包 ,并且应该记录事件. 接下来,使用步骤 2 中的翻转计数器、密码上下文中指示的身份验证算法和步骤 4 中的session authentication key 执行身份验证标签的验证。如果结果是“身份验证失败”(请参阅第 4.2 节),则 数据包必须从进一步处理中被丢弃并且事件应该被记录。
-
使用密码上下文中指示的解密算法、步骤 4 中找到的session key和session salt(如果使用)以及步骤 2 中的索引,解密数据包的加密部分
-
使用步骤 2 中估计的数据包索引,更新加密上下文中的翻转计数器和最高序列号 s_l,如果提供了重放保护,还应更新重放列表。
-
如果存在,请从数据包中删除 MKI 和身份验证标记字段 (SRTP特有的,RTP是没有的,最后要给的是一个RTP包)。
会话密钥派生
无论采用何种加密或消息身份验证转换,SRTP必须使用SRTP naster key 派生 session key。一旦在会话开始时正确地使用信号(握手)通知(协商)密钥派生率(key_derivation_rate),未来使用SRTP密钥派生的各方之间就不需要额外的通信(根据 master key 和 密钥派生率 派生即可)。
因此,在key_derivation_rate关联的master key的生命周期内,key_derivation_rate 必须是保持固定的。
packet index ---+
|
v
+-----------+ master +--------+ session encr_key
| ext | key | |---------->
| key mgmt |-------->| key | session auth_key
| (optional | | deriv |---------->
| rekey) |-------->| | session salt_key
| | master | |---------->
+-----------+ salt +--------+
令 r = index DIV key_derivation_rate (“a DIV t” 表示 a 除以 t 的整数除法,四舍五入,请注意,对于 key_derivation_rate 为 0,密钥的应用推导应恰好发生一次。)
令 key_id = <label> || r
令 x = key_id XOR master_salt
则一个 n 位 的 SRTP key or salt 可以使用算法PRF从 master key 中派生:PRF_n(master_key, x)
其中:
- index:是 SRTP Packet Index (索引)
- key_derivation_rate:是已和通信对方协商好的密钥派生率
- k_e (SRTP encryption (SRTP加密密钥)):<label>=0x00, n=n_e
- k_a (SRTP message authentication (SRTP信息完整性校验密钥)):<label>=0x01, n=n_a
- k_s (SRTP salting key): <label>=0x01, n=n_a
其中:
- n_e、n_a 和 n_s 都是从加密上下文中获取的,分别表示 k_e的位长,k_a 的位长,k_s 的位长
- 主密钥和主盐必须是随机的(握手协商得来的),但主盐可能是公开的。
SRTCP 密钥推导
对于 SRTCP,将 SRTP 索引替换为 32 位数量:0 || SRTCP索引(即排除E位,用固定的0位代替),并使用:
<label> = 0x03 用于 SRTCP 加密密钥,
<label> = 0x04 用于SRTCP 身份验证密钥,
<label> = 0x05 用于 SRTCP salting key。
加密转换
在 SRTP 中,加密转换将 SRTP Packet Index 和 密钥 映射成一个密钥流段。每个密钥流段被用于加密一个 RTP 包(Index对应的RTP包)。
因此加密转换可以分为两步:
- 生成与该数据包对应的密钥流段
- 将该密钥流段按位异或到 RTP 数据包的有效载荷上以生成 SRTP 数据包的加密部分。如果有效载荷大小不是 n_b 的整数倍,则密钥流段的多余位将被简单地丢弃。
解密以相同地方式完成。但交换了明文和密文的角色。
默认的SRTP加密过程如下:
+----+ +------------------+---------------------------------+
| KG |-->| Keystream Prefix | Keystream Suffix |---+
+----+ +------------------+---------------------------------+ |
|
+---------------------------------+ v
| Payload of RTP Packet |->(*)
+---------------------------------+ |
|
+---------------------------------+ |
| Encrypted Portion of SRTP Packet|<--+
+---------------------------------+
每个密钥流段的最初的字节可以保留用于消息验证代码,在这种情况下,用于加密的密钥流从最后保留的字节之后开始。最初保留的字节称为 Keystream Prefix (密钥流前缀),其余字节称为 Keystream Suffix (密钥流后缀)。密钥流前缀不得用于加密。
密钥流前缀中的字节个数表示为 SRTP_PREFIX_LENGTH 。
给定 index,如何生成 Keystream ?这取决于 密码 和 密码的操作模式。
默认密码是 AES,这里介绍两种运行 AES 的操作模式:(1) 分段整数计数器模式 AES 和 (2) f8 模式下的 AES。
AES计数器模式
令 E(k, x)是应用于密钥 k 和 输入 x 的 AES 输出。
计数器模式下,密钥流段应是AES密码在加密方向上的串联,其中块索引按递增顺序排列,因此,每个密
钥流看起来像:
E(k, IV) || E(k, (IV + 1) mod 2^128) >> 128 || E(k, (IV + 2) mod 2^128) >> 128*2
其中:
k = k_e
IV = (k_s * 2^16) XOR (SSRC * 2^64) XOR (i * 2^16)
- k_e :是 session key
- k_s :是 session salt key
- SSRC :是 SSRC
- i :是 SRTP Packet index
上述 XOR 中的三项,都填充了所需的前导零,已满足 128 位。
实际上:
IV = (k_s << 16) XOR (SSRC << 64) XOR (i << 16)
相当于IV预留了16位,实际上这16位被用来计数 count,AES每加密 128-bits 数据对 count 进行 + 1,相当于将 IV + count 作为 AES的一个输入,如下:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| IV | count +
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
在SRTCP中,使用SRTCP中 compound中的第一个header的SSRC ,使用 SRTCP中的index,使用 SRTCP 的 k_e 和 k_s。
AES-f8 模式
为了加密 UMTS(通用移动电信系统,作为 3G 网络)数据,已经开发了一种称为 f8-算法的解决方案(参见 [f8-a] [f8-b])。 在高层次上,所提出的方案是输出反馈模式 (OFB) [HAC] 的一种变体,具有更精细的初始化和反馈功能。 与普通 OFB 一样,核心由分组密码组成。 我们还在此处定义使用 AES 作为块密码,用于我们将称之为“f8 操作模式”的 RTP 加密。 AES f8 模式应使用与 AES 计数器模式相同的会话密钥和盐的默认大小。
这里不再展开
空密码
当不要求 RTP/RTCP 机密性时,将使用 NULL 密码。 密钥流可以被认为是“000..0”,即加密应该简单地将明文输入复制到密文输出中。
消息认证和完整性
设 M 表示数据完整性受保护,则在SRTP中,M = Authenticated Portion || ROC ,在SRTCP 中,M = Authenticated Portion 。
共同参数有:
- AUTH_ALG:认证算法(常见:HMAC-SHA1)
- k_a:会话消息认证密钥
- n_a:k_a的位长
- n_tag:输出的认证标签的位长
- SRTP_PREFIX_LENGTH:密钥流前缀的字节长度(AUTH_ALG的一个参数)
消息认证和完整性验证过程:发送方计算 M 的 tag1 并将其附加到数据包中。接收方使用特定的算法和密钥,计算 M 的 tag2,接收方将 tag1 和 tag2 进行比较,如果两个tag相等,则消息/身份有效,否则无效,并返回失败 “AUTHENTICATION“ 错误。
其他
重放保护
只有在存在完整性保护时才能进行安全重放保护。建议对 RTP 和 RTCP 都使用重放保护,因为单独的完整性保护不能保证安全,需要防止重放攻击。
数据包在被对手存储时被“重放”,然后重新注入网络。当提供消息身份验证时,SRTP 通过重播列表防止此类攻击。每个 SRTP 接收器都维护一个重放列表,它在概念上包含所有已接收和验证的数据包的索引。在实践中,列表可以使用“滑动窗口”方法,这样固定数量的存储就足以进行重放保护。
接收器根据重放列表和窗口检查传入数据包的索引。只有索引位于窗口之前的数据包,或者在窗口内但尚未收到的数据包,才应被接受。
在数据包被认证后(如有必要,窗口首先向前移动),重放列表应使用新索引更新。
重放列表可以通过使用 bit map 来表示哪些数据包已被接收来有效地实现
为什么要使用密钥派生
密钥派生减少了密钥建立的负担,每个加密上下文需要多达六个不同的密钥(SRTP和SRTCP加密密钥和solt、 SRTP和SRTCP身份验证密钥),这些密钥现在是以加密安全的方式从单个主密钥派生的。因此密钥管理协议只需要交换一个主密钥(在需要时加上master salting),然后SRTP本身导出所有必要的会话密钥(通过密钥导出函数)。
密钥派生功能的多个应用程序是可选的,但在启用时将提高安全优势。它们防止攻击者获得单个固定会话密钥产生的大量密文。如果攻击者能够为某个会话密钥收集大量密文,则可能有助于发起某些攻击。
密钥派生函数的多个应用程序提供了向后和向前的安全性,会话密钥不会危机从同一个主密钥派生的其他会话密钥。这意味着能够破解某个会话密钥的攻击者无论如何都无法访问之前和之后的会话密钥(源自相同的主密钥)保护的消息。
因此我们可以在需要的时候刷新会话密钥,当然频繁的密钥刷新会出现一些注意事项,尤其是在多播的时候。
Salting key的作用是什么?
salting key 也是key,顾名思义是:盐,用于在加密中加点料,防止某些可能存在的异常或冲突或攻击。
master salt 用于防止针对密钥派生的离线密钥冲突攻击, 否则可能会减少有效密钥的数量(因冲突而减少)
加密中使用的 session salt 被引入用于防止针对附加流密码的某些攻击。
SSRC 冲突 和 two-time pad
从相同的密钥和索引生成的任何固定密钥流必须仅用于一次加密。重复使用这样的密钥流,会严重危害安全性。因此要求使用自动密钥管理来建立和维护SRTP和SRTCP密钥材料,避免密钥流重用(手动密钥管理更可能发生这种情况)。除此之外,在SRTP中,通过要求密钥或其他具有加密意义的参数对每个RTP/RTCP流和数据包是唯一的,可以避免“two-time pad“。
预定义的SRTP变换通过 数据包的索引和SSRC唯一性来实现数据包的唯一性。
通过在IV中包含SSRC,预定义的转换(AES-CM和AES-f8)允许在属于同一RTP会话的流之间共享主密钥。主密钥不得在不同的RTP会话之间共享。
因此,SSRC在共享相同主密钥的同一RTP会话中的所有RTP流之间必须是唯一的。RTP本身提供了一种算法,用于检测同一RTP会话中的SSRC冲突。但,密钥管理还是应该注意避免此类SSRC冲突,应该将会话中使用的SSRC作为协商参数包含在内,主动确保它们的唯一性,这是一个很强的要求。
注意,即使有不同的SSRC,但大量使用相同的密钥也可能提高概率攻击和时间内存权衡攻击成功率。如前所述,主密钥可以在属于同一RTP会话的流之间共享,但建议每个SSRC都有自己的主密钥。当主密钥在SSRC参与者之间共享并且SSRC由密钥管理模块时,当出现SSRC冲突时,会话者应该离开SRTP会话,因为这是故障。
密钥的有效性
有效密钥大小取决于 master key 的大小和 salting key 的大小。
任何附加流密码都容易受到攻击,这些攻击使用有关明文源的统计知识来实现密钥冲突和时间-内存权衡攻击[MF00][H80][BS00]。这些攻击利用明文之间的共性,并为密码分析者提供了一种方法来分摊对许多密钥或许多输出字节进行解密的计算工作,从而减少密码的有效密钥大小。
[MF00]中提供了对这些攻击及其对Internet流量加密的适用性的详细分析。总之,当在使用m个不同密钥的安全系统中使用SRTP时,SRTP的有效密钥大小等于密码的密钥大小减去m的对数。
可以简单地通过增加所用密钥的大小来提供针对此类攻击的保护,这里可以使用salting key来实现。请注意,salting key必须是随机的,但可以是公开的。使用112位的盐最多能防止 2的112次方个密钥被攻击。
在预定义转换中使用 SRTP 和 SRTCP 索引确定可以使用相同会话密钥保护的最大数据包数。当 SRTP 和 SRTCP 被独立考虑(独立的计数)时,此限制固定为 2 的 48次方 个SRTP数据包和 2 的31次方个 SRTCP数据包。但是,由于重新(重复)加密,因此达到此限制时会不与索引一致,因此发送方必须对数据包进行计数。当SRTP和SRTCP的会话密钥来自相同的主密钥时(默认是来自相同的主密钥),此时就必须考虑受保护的最大数据包数是两者的最小值,当受保护的SRTP或SRTCP达到相应的个数后,就必须调用密钥管理以提供新的主密钥,或者会话必须终止。
当然,即使在 200 SRTCP 数据包/秒,SRTCP 的 2^31 索引空间是足以确保大约 4 个月的通信。
当在同一RTP会话中的SRTP流之间(不同的SSRC)共享主密钥时,尽管上述界限是基于每个流(即每个SSRC)(因为每个流采用一个session key)的,但发送方必须基于序列号空间最先耗尽的流做出决策(调用密钥管理以提供新的主密钥,或者会话必须终止)
网友评论