Encryption WebRTC SRTP解密

Encryption WebRTC SRTP解密,encryption,webrtc,rtp,des,dtls,Encryption,Webrtc,Rtp,Des,Dtls,我正在尝试构建一个SRTP到RTP流转换器,从我正在创建的WebRTC对等连接获取主密钥时遇到问题 据我所知,对于a,密钥是通过SDP交换进行交换的,并显示在a=crypto字段中。因此,这种情况看起来非常直截了当(如果我错了,请纠正我),但最终毫无用处,因为WebRTC标准化现在要求不使用DES(只有Chrome现在支持它,将来可能会删除它) 因为SDP中有指纹字段,这是要在未来交换中使用的哈希吗?[编辑:在阅读了一些内容后,我认为情况并非如此]我会认为,有了指纹的知识以及通过交换中的DTLS

我正在尝试构建一个
SRTP
RTP
流转换器,从我正在创建的
WebRTC对等连接获取
主密钥时遇到问题

据我所知,对于a,密钥是通过
SDP
交换进行交换的,并显示在
a=crypto
字段中。因此,这种情况看起来非常直截了当(如果我错了,请纠正我),但最终毫无用处,因为
WebRTC
标准化现在要求不使用DES(只有
Chrome
现在支持它,将来可能会删除它)

因为
SDP
中有指纹字段,这是要在未来交换中使用的哈希吗?[编辑:在阅读了一些内容后,我认为情况并非如此]我会认为,有了指纹的知识以及通过交换中的DTLS数据包进行解析的能力,我应该能够抓取
主密钥来解码SRTP流,但我遇到了麻烦,因为我不知道去哪里看,甚至100%确定这是否可能


这样,简而言之,即使没有进入下一个C++ API,并创建我自己的实现“代码> WebRTC < /COD>”,也可以解码<代码> SRTP < /代码>提要,该代码是用<代码> WebRTC PeerConnection <代码>在<代码> Chrome 和<代码> Firefox >中进行解码的。(可能通过使用从

SDP
交换收集的信息进行数据包嗅探)?[编辑:令人沮丧的是,似乎无法访问密钥的私有部分(即主密钥)…如果我错了,请更正]

我找到了“SSL导出密钥”材料 它可以从SSL机制(DTLS握手后)获取密钥并将其用于SRTP


我不是专家,只是像你一样撞到了墙…

有些代码使用openssl和libsrtp原生api

#define SRTP_MASTER_KEY_KEY_LEN 16
#define SRTP_MASTER_KEY_SALT_LEN 14
static void dtls_srtp_init( struct transport_dtls *dtls )
{

/*
  When SRTP mode is in effect, different keys are used for ordinary
   DTLS record protection and SRTP packet protection.  These keys are
   generated using a TLS exporter [RFC5705] to generate

   2 * (SRTPSecurityParams.master_key_len +
        SRTPSecurityParams.master_salt_len) bytes of data

   which are assigned as shown below.  The per-association context value
   is empty.

   client_write_SRTP_master_key[SRTPSecurityParams.master_key_len];
   server_write_SRTP_master_key[SRTPSecurityParams.master_key_len];
   client_write_SRTP_master_salt[SRTPSecurityParams.master_salt_len];
   server_write_SRTP_master_salt[SRTPSecurityParams.master_salt_len];
*/
  int code;
  err_status_t     err;
  srtp_policy_t policy;
  char dtls_buffer[SRTP_MASTER_KEY_KEY_LEN * 2 + SRTP_MASTER_KEY_SALT_LEN * 2];
  char client_write_key[SRTP_MASTER_KEY_KEY_LEN + SRTP_MASTER_KEY_SALT_LEN];
  char server_write_key[SRTP_MASTER_KEY_KEY_LEN + SRTP_MASTER_KEY_SALT_LEN];
  size_t offset = 0;

  /*
   The exporter label for this usage is "EXTRACTOR-dtls_srtp".  (The
   "EXTRACTOR" prefix is for historical compatibility.)
   RFC 5764 4.2.  Key Derivation
  */
  const char * label = "EXTRACTOR-dtls_srtp";

  SRTP_PROTECTION_PROFILE * srtp_profile= SSL_get_selected_srtp_profile( dtls->ssl );

/* SSL_export_keying_material exports a value derived from the master secret,
 * as specified in RFC 5705. It writes |olen| bytes to |out| given a label and
 * optional context. (Since a zero length context is allowed, the |use_context|
 * flag controls whether a context is included.)
 *
 * It returns 1 on success and zero otherwise.
 */
  code = SSL_export_keying_material(dtls->ssl, 
                                    dtls_buffer, 
                                    sizeof(dtls_buffer),
                                    label, 
                                    strlen( label),
                                    NULL,
                                    0, 
                                    PJ_FALSE);

  memcpy(&client_write_key[0], &dtls_buffer[offset], SRTP_MASTER_KEY_KEY_LEN);
  offset += SRTP_MASTER_KEY_KEY_LEN;
  memcpy(&server_write_key[0], &dtls_buffer[offset], SRTP_MASTER_KEY_KEY_LEN);
  offset += SRTP_MASTER_KEY_KEY_LEN;
  memcpy(&client_write_key[SRTP_MASTER_KEY_KEY_LEN], &dtls_buffer[offset], SRTP_MASTER_KEY_SALT_LEN);
  offset += SRTP_MASTER_KEY_SALT_LEN;
  memcpy(&server_write_key[SRTP_MASTER_KEY_KEY_LEN], &dtls_buffer[offset], SRTP_MASTER_KEY_SALT_LEN); 

  switch( srtp_profile->id )
  {
  case SRTP_AES128_CM_SHA1_80:
    crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp);
    crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
    break;
  case SRTP_AES128_CM_SHA1_32:
    crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp);   // rtp is 32,
    crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);  // rtcp still 80
    break;
  default:
    assert(0);
  }
  policy.ssrc.value = 0;
  policy.next = NULL;

  /* Init transmit direction */
  policy.ssrc.type = ssrc_any_outbound;  
  policy.key = client_write_key;    

  err = srtp_create(&dtls->srtp_ctx_rx, &policy);
  if (err != err_status_ok) {
    printf("not working\n");
  } 

  /* Init receive direction */
  policy.ssrc.type = ssrc_any_inbound;  
  policy.key = server_write_key;    

  err = srtp_create(&dtls->srtp_ctx_tx, &policy);
  if (err != err_status_ok) {
    printf("not working\n");
  } 

}

不清楚这是否是您的情况,但请注意,仅作为被动观察者,不可能从SRTP(即:未加密)访问音频/视频-这就是传输加密的全部意义

协议(DTLS-SRTP)的工作原理大致如下:

  • 每个浏览器都有一个唯一的密钥对,通常在安装时生成
  • SDP、报价和答复中包含的每一方的报价
  • 两端通过协商DTLS连接,从而导出一种会话密钥,用于保护(DTLS)连接
如果您无法访问密钥对的至少一个私钥部分,则根本无法解密连接。如果端点选择在握手时使用,则被动攻击者将无法获取派生密钥,即使可以访问两个私钥。此属性称为


访问SRTP内容的唯一可靠方法是亲自握手,实施活动MITM(更改SDP上的指纹)或从浏览器获取私钥,并限制DH密钥交换(AFAIK,这根本不可能)

相关:我认为目前唯一的选择是使用本机API,而不是主流浏览器实现。杜德,我喜欢!这是特定项目的一部分吗?Tanks,bwtrent!它是CrystalVu SDK()的一部分,提供与sipml5()的互操作性