zoukankan      html  css  js  c++  java
  • dtls_srtp学习笔记

    注:以下为rfc5764的学习笔记,不保证完全正确。

    DTLS-SRTP是DTLS的一个扩展,将SRTP加解密与DTLS的key交换和会话管理相结合。从SRTP的角度看,是为其提供一种新的key协商管理的方法;从DTLS的角度看,是为应用数据提供一个新的数据格式(SRTP/SRTCP)。

    1,应用层数据加解密是由SRTP完成的,要求必须是RTP/RTCP的格式。
    2,DTLS的握手过程是为SRTP加解密过程协商使用哪种profile和密钥。
    3,除了应用数据加密为SRTP格式,其他record-layer的报文仍为普通的DTLS格式(比如TLS control message)
    4,当发送SRTP格式的应用层数据时,需要直接跳过DTLS加密层,将SRTP数据包透传到下层的数据传输层做发送。

    由于密钥和加密参数是在DTLS握手过程中协商得到的,而此过程是保密的,因而相比常规的方式(比如在通过SDP消息交互来协商)更为安全。在发起DTLS握手之前,需要先设置use-srtp扩展。

    接收端使用 DTLS-SRTP
    自DTLS下层的传输层收到报文之后,需要根据包头特征手动区分做demultiplexing,一般可以如下进行
    检查第一个报文的第一个字节
    1,是[0, 1]时,表示可能是STUN报文
    2,是[128, 191]时,表示可能时RTP(SRTP)报文
    3,是[20, 63]时,表示可能是DTLS record layer报文
    其他的类别请根据实际情况做区分处理

    DTLS握手成功之后,需要导出key material,然后从中分离出server/client端用于SRTP对称加密的密钥。key material中对应SRTP的密钥,构成如下

    client_master_key server_master_key client_salt server_salt

    其中 master_key 和 salt 的长度是根据最终协商的 SRTP 的profile来确定的,具体可查 RFC3711 SRTP

    key material导出的规范见 RFC5705 Keying Material Exporters for TLS

    webrtc中对此代码实现见,webrtc/pc/channel.cc中 BaseChannel::SetupDtlsSrtp_n() 函数

    Code Sample using DTLS-SRTP

     1 #define SRTP_MASTER_KEY_KEY_LEN 16
     2 #define SRTP_MASTER_KEY_SALT_LEN 14
     3 static void dtls_srtp_init( struct transport_dtls *dtls )
     4 {
     5 
     6 /*
     7   When SRTP mode is in effect, different keys are used for ordinary
     8    DTLS record protection and SRTP packet protection.  These keys are
     9    generated using a TLS exporter [RFC5705] to generate
    10 
    11    2 * (SRTPSecurityParams.master_key_len +
    12         SRTPSecurityParams.master_salt_len) bytes of data
    13 
    14    which are assigned as shown below.  The per-association context value
    15    is empty.
    16 
    17    client_write_SRTP_master_key[SRTPSecurityParams.master_key_len];
    18    server_write_SRTP_master_key[SRTPSecurityParams.master_key_len];
    19    client_write_SRTP_master_salt[SRTPSecurityParams.master_salt_len];
    20    server_write_SRTP_master_salt[SRTPSecurityParams.master_salt_len];
    21 */
    22   int code;
    23   err_status_t     err;
    24   srtp_policy_t policy;
    25   char dtls_buffer[SRTP_MASTER_KEY_KEY_LEN * 2 + SRTP_MASTER_KEY_SALT_LEN * 2];
    26   char client_write_key[SRTP_MASTER_KEY_KEY_LEN + SRTP_MASTER_KEY_SALT_LEN];
    27   char server_write_key[SRTP_MASTER_KEY_KEY_LEN + SRTP_MASTER_KEY_SALT_LEN];
    28   size_t offset = 0;
    29 
    30   /*
    31    The exporter label for this usage is "EXTRACTOR-dtls_srtp".  (The
    32    "EXTRACTOR" prefix is for historical compatibility.)
    33    RFC 5764 4.2.  Key Derivation
    34   */
    35   const char * label = "EXTRACTOR-dtls_srtp";
    36 
    37   SRTP_PROTECTION_PROFILE * srtp_profile= SSL_get_selected_srtp_profile( dtls->ssl );
    38 
    39 /* SSL_export_keying_material exports a value derived from the master secret,
    40 * as specified in RFC 5705. It writes |olen| bytes to |out| given a label and
    41 * optional context. (Since a zero length context is allowed, the |use_context|
    42 * flag controls whether a context is included.)
    43 *
    44 * It returns 1 on success and zero otherwise.
    45 */
    46   code = SSL_export_keying_material(dtls->ssl, 
    47                                     dtls_buffer, 
    48                                     sizeof(dtls_buffer),
    49                                     label, 
    50                                     strlen( label),
    51                                     NULL,
    52                                     0, 
    53                                     PJ_FALSE);
    54 
    55   memcpy(&client_write_key[0], &dtls_buffer[offset], SRTP_MASTER_KEY_KEY_LEN);
    56   offset += SRTP_MASTER_KEY_KEY_LEN;
    57   memcpy(&server_write_key[0], &dtls_buffer[offset], SRTP_MASTER_KEY_KEY_LEN);
    58   offset += SRTP_MASTER_KEY_KEY_LEN;
    59   memcpy(&client_write_key[SRTP_MASTER_KEY_KEY_LEN], &dtls_buffer[offset], SRTP_MASTER_KEY_SALT_LEN);
    60   offset += SRTP_MASTER_KEY_SALT_LEN;
    61   memcpy(&server_write_key[SRTP_MASTER_KEY_KEY_LEN], &dtls_buffer[offset], SRTP_MASTER_KEY_SALT_LEN); 
    62 
    63   switch( srtp_profile->id )
    64   {
    65   case SRTP_AES128_CM_SHA1_80:
    66     crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp);
    67     crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
    68     break;
    69   case SRTP_AES128_CM_SHA1_32:
    70     crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp);   // rtp is 32,
    71     crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);  // rtcp still 80
    72     break;
    73   default:
    74     assert(0);
    75   }
    76   policy.ssrc.value = 0;
    77   policy.next = NULL;
    78 
    79   /* Init transmit direction */
    80   policy.ssrc.type = ssrc_any_outbound;  
    81   policy.key = client_write_key;    
    82 
    83   err = srtp_create(&dtls->srtp_ctx_rx, &policy);
    84   if (err != err_status_ok) {
    85     printf("not working
    ");
    86   } 
    87 
    88   /* Init receive direction */
    89   policy.ssrc.type = ssrc_any_inbound;  
    90   policy.key = server_write_key;    
    91 
    92   err = srtp_create(&dtls->srtp_ctx_tx, &policy);
    93   if (err != err_status_ok) {
    94     printf("not working
    ");
    95   } 
    96 
    97 }
  • 相关阅读:
    不知道微博的计时机制
    Edsger W. Dijkstra
    最靠谱百度网盘下载太慢的解决办法
    这个拒绝成为比尔盖茨的“互联网之父”,今天拿下了计算机届的诺贝尔奖!
    老罗语录
    如何利用互联网免费学习英语
    wps怎么制作一个红色的电子印章?
    安防摄像头视频流媒体服务器EasyDSS如何配置接入考场监控系统?
    互联网流媒体直播点播平台报ioutil.WriteFile错误导致文件只读如何处理?
    互联网直播点播平台go语言搭建重定向和反向代理的区别及使用
  • 原文地址:https://www.cnblogs.com/lanyuliuyun/p/8289306.html
Copyright © 2011-2022 走看看