SRTP 协议是什么?SRTP 协议格式及加密介绍

SRTP协议是什么

SRTP,即安全实时传输协议(Secure Real-time Transport Protocol),是在实时传输协议(Real-time Transport Protocol)基础上所定义的一个协议。

SRTP协议格式

  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 ---+

字段介绍

前面12个字节和CSRC与RTP头中相应字段完全一样,唯一不同的是SRTP新添加了MKI和authentication tag两个字段, 两个字段位于加密body的尾部。

rtp头各字段的含义等到下篇介绍RTP时再介绍。

SRTP MKI

MKI :Master Key Identifier,主密钥标识。

srtp有两种类型的key,一个是master key,一个是session  key。通过dtls协商的秘钥是和master key相关的,内部会经过一定的处理逻辑最终生成session key(生成规则见文章末尾),通过session key对数据进行加密。

不同的会话对应不同的session key,而MKI的值其实是session key 的mki_id, 用来区分不同的session key。

具体代码如下:

unsigned int srtp_inject_mki(uint8_t *mki_tag_location,
                             srtp_session_keys_t *session_keys,
                             unsigned int use_mki)
{
    unsigned int mki_size = 0;

    if (use_mki) {
        mki_size = session_keys->mki_size;

        if (mki_size != 0) {
            // Write MKI into memory
            //把session_keys的mki_id 填到mki字段
            memcpy(mki_tag_location, session_keys->mki_id, mki_size);
        }
    }

    return mki_size;
}
转到session_keys结构定义处,会看到mki_id的说明,它是用来确定session keys
/*
 * srtp_session_keys_t will contain the encryption, hmac, salt keys
 * for both SRTP and SRTCP.  The session keys will also contain the
 * MKI ID which is used to identify the session keys.
 */
typedef struct srtp_session_keys_t {
    srtp_cipher_t *rtp_cipher;
    srtp_cipher_t *rtp_xtn_hdr_cipher;
    srtp_auth_t *rtp_auth;
    srtp_cipher_t *rtcp_cipher;
    srtp_auth_t *rtcp_auth;
    uint8_t salt[SRTP_AEAD_SALT_LEN];
    uint8_t c_salt[SRTP_AEAD_SALT_LEN];
    uint8_t *mki_id;
    unsigned int mki_size;
    srtp_key_limit_ctx_t *limit;
} srtp_session_keys_t;

通过看srtp源码,发现并没有用mki,默认取session_keys列表中的第一个值作为session key。

加密时use_mki和mki_index都为0,同样解密时mki_index也为0。

srtp_err_status_t srtp_protect(srtp_ctx_t *ctx,
                               void *rtp_hdr,
                               int *pkt_octet_len)
{
   //use_mki和mki_index两个参数都是0
    return srtp_protect_mki(ctx, rtp_hdr, pkt_octet_len, 0, 0);
}

srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx,
                                   void *rtp_hdr,
                                   int *pkt_octet_len,
                                   unsigned int use_mki,
                                   unsigned int mki_index)
                                   

authentication tag

SRTP包的认证tag,认证的的数据由RTP头和SRTP包的加密部分组成。就是对数据进行签名,然后收到消息后再进行一次,对比两次生成的结果是否相等,来确定数据是否正确。

SRTP对RTP加密时只加密RTP的playload部分,不加密RTP头。代码如下

 /*
     * find starting point for encryption and length of data to be
     * encrypted - the encrypted portion starts after the rtp header
     * extension, if present; otherwise, it starts after the last csrc,
     * if any are present
     *
     * if we're not providing confidentiality, set enc_start to NULL
     */
    if (stream->rtp_services & sec_serv_conf) {//跳过rtp header
        enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc;
        if (hdr->x == 1) {
            xtn_hdr = (srtp_hdr_xtnd_t *)enc_start;
            enc_start += (ntohs(xtn_hdr->length) + 1);
        }
        /* note: the passed size is without the auth tag */
        if (!((uint8_t *)enc_start <= (uint8_t *)hdr + *pkt_octet_len))
            return srtp_err_status_parse_err;
        enc_octet_len =
            (int)(*pkt_octet_len - ((uint8_t *)enc_start - (uint8_t *)hdr));
        if (enc_octet_len < 0)
            return srtp_err_status_parse_err;
    } else {
        enc_start = NULL;
    }

所以,如果项目中是以SSRC为key保存用户信息,当收到SRTP包无需解密也可以获得包中的SSRC,从而找到用户。   

但是,对于rtp的扩展头是加密的,代码如下,详情见RFC6904

 if (xtn_hdr && session_keys->rtp_xtn_hdr_cipher) {
    /*
    * extensions header encryption RFC 6904
     */
   status = srtp_process_header_encryption(stream, xtn_hdr, session_keys);
   if (status)
   {
         return status;
   }
 }

srtp加密上下文信息

描述srtp加密时用的一些基础知识,参数信息

  • ROC (Rollover Counter) 序列号重置

rtp的序列号占16位,当超过最大值时,序列号会再从零开始,因为包又从零开始,那怎么区分不同的包呢?为了解决这个问题,引入了重置次数ROC,重置后RTP包序列号计算公式:

 i = 2^16 * ROC + SEQ

每重置一次相当于经过了2^16个包,重置几次既有几个2^16次方,SEQ是当前RTP包头中的序列号。

  • master saltmaster key的”盐值”,就是对master key加上一些随机值,然后进行散列。

基于master key和master salt推导出实际加密rtp时用的session key。

 packet index ---+
                                         |
                      v
+-----------+ master  +--------+ session encr_key
| ext       | key     |        |---------->
| key mgmt  |-------->|  key   | session auth_key
| (optional |         | deriv  |---------->
| rekey)    |-------->|        | session salt_key
|           | master  |        |---------->
 +-----------+ salt    +--------+

作者:音视频之路

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论