【stun系列03】对于stun协议头的理解

1:STUN消息头

  消息头有20个字节组成:00 + 消息类型  + 消息体长度 + 魔术字 + 事务ID

  • 前2个字节:
  1.   其中00占2位:固定全是0
  2.   消息类型占14位:其中根据消息头的前两个字节和C1C0划分为0x000:请求,0x001:指示,0x010:成功响应,0x011:错误响应。则消息方法只有Binding(0x01)

    根据消息类型和方法交集 可以分为,Binding请求(0x00 01),Binding成功响应(0x01 01),Binding失败响应(0x01 11),Binding指示(0x00 11)。其中指示消息用的很少,可以不需要管。

  • 消息体长度占16位:是消息体部分的总长度,由于4字节对齐特性,长度字段最后2位也全是0
  • 魔术字占32位:4个字节,是固定值0x2112A442
  • 事务ID占96位:12个字节,是由客户端随机生成的12字节随机值

  自此,消息头如何生成和填充已经确定

2:常用的请求的TLV属性生成规则

  TLV属性是:属性type + 属性长度 + 属性值

2.1:USERNAME

  属性type:两个字节,为0x0006

  属性长度:两个字节,是属性值的长度,即后续填充的value的长度

  属性值:可变长度的,用户名的内容+填充字段(填充完保证4字节对齐)

2.2:MESSAGE-INTEGRITY

  Request 和 Response 时 需要使用不同的密码加密生成该字段;

  如果是主动发送Request需要使用对端ice密码进行加密

  如果是回复对端Response需要使用本端ice密码加密并回复

  属性类型:0x0008

  属性长度:固定20个字节

  属性值:短期认证:HMAC-SHA1计算的password值。计算方法:HMAC_SHA1(PASSWORD)

      长期认证:MD5(username ":" realm ":" SASLprep(password))

  对于短期认证计算网址:https://www.liavaag.org/English/SHA-Generator/HMAC/

  其中对于text部分和key部分需要特别注意

  text:STUN的包头+属性集合到MESSAGE-INTEGRITY位置,后续的属性不计算在内,但是需要更改stun的包头的length值,此长度需要包含MESSAGE-INTEGRITY的长度,但不包含后面属性的长度。

举例:

  192.168.239.1端ice密码:

    a=ice-ufrag:13BZ

    a=ice-pwd:GT82bdkfK4dxuVsrc/Dv3EqV

 

  192.168.239.140端ice密码:

    a=ice-ufrag:67v27075

    a=ice-pwd:745s295z8lv458ll46w2467ta460562n

HMAC的输入是stun的包的内容:

00 01 00 50 21 12 a4 42 78 2b 66 6b 32 34 30 6b
4e 51 6a 56 00 06 00 0d 36 37 76 32 37 30 37 35
3a 31 33 42 5a 00 00 00 c0 57 00 04 00 02 00 00
80 2a 00 08 70 fb e5 05 91 bf 83 3c 00 24 00 04
6e 7e 1e ff 00 08 00 14 c7 c4 9a 60 94 6f a0 24
e5 f6 21 2e c6 38 14 fe 2e 76 b2 6d 80 28 00 04
3a c7 02 9f

1:先修改stun的头部长度值,为消息属性长度减去message-integrity后面属性的长度。因为只有一个fingeprint,长度为8,所以改成48

  50 - 8 -> 48

修改后如下:

00 01 00 48 21 12 a4 42 78 2b 66 6b 32 34 30 6b
4e 51 6a 56 00 06 00 0d 36 37 76 32 37 30 37 35
3a 31 33 42 5a 00 00 00 c0 57 00 04 00 02 00 00
80 2a 00 08 70 fb e5 05 91 bf 83 3c 00 24 00 04
6e 7e 1e ff 00 08 00 14 c7 c4 9a 60 94 6f a0 24
e5 f6 21 2e c6 38 14 fe 2e 76 b2 6d 80 28 00 04
3a c7 02 9f

2:作为HMAC的输入时,需要剔除fingeprint+message-integrity的属性

修改后如下:

00 01 00 48 21 12 a4 42 78 2b 66 6b 32 34 30 6b
4e 51 6a 56 00 06 00 0d 36 37 76 32 37 30 37 35
3a 31 33 42 5a 00 00 00 c0 57 00 04 00 02 00 00
80 2a 00 08 70 fb e5 05 91 bf 83 3c 00 24 00 04
6e 7e 1e ff 00 08 00 14 c7 c4 9a 60 94 6f a0 24
e5 f6 21 2e c6 38 14 fe 2e 76 b2 6d 80 28 00 04
3a c7 02 9f

将此内容作为输入,key为answer的密码:745s295z8lv458ll46w2467ta460562n,经过网站 ( https://www.liavaag.org/English/SHA-Generator/HMAC/ )校验后内容为

 

内容与抓包的数据值相同

2.3:FINGERPRINT

  属性类型:0x8028

  属性长度:固定是4字节,因为值是经过4字节异或的。

  属性值:0x5354554e异或CRC32(内容); 内容是STUN头(20字节)+STUN属性体 (排除本属性)的buffer,且buffer内容是整个内容填充好后的buffer ;截取长度是HEADER.length + 20 - 8(fingerprint属性长度)

  例如:buffer内容去红框内,且头的len字段不需要修改

  

    计算crc32

https://www.lammertbies.nl/comm/info/crc-calculation   或者

http://sunshine2k.de/coding/javascript/crc/crc_js.html

  

  计算后的crc32是0x712D1962 与 0x5354554e 取异或 = 

http://xor.pw/#

   

 

 2.4:ICE-CONTROLED

  属性类型:0x8029

  属性长度:固定是8字节

  属性值:Tie breaker: 是一个64bits的随机值

2.5:ICE-CONTROLLING

  属性类型:0x802a

  属性长度:固定是8字节

  属性值:Tie breaker: 是一个64bits的随机值

2.6:XOR-MAPPED-ADDRESS

  属性类型:0x0020

  属性长度:IPV4:8字节;IPV6:20字节

  属性值:8位的固定值0 + 8位的协议簇类型 + 16位的端口号 + 地址异或

    协议簇类型为:1:IPV4;2:IPV6

    端口号:{}端口号} 异或 {魔术字的前2个字节(0x2112)}

    地址:{IPV4是4字节} 异或 {魔术字(magic cookie)}

       {IPV6是16字节} 异或 {魔术字(magic cookie) + 事务ID}

 

3:如果端口复用

  需要根据stun的关键位判断进行解复用。

posted @ 2021-11-14 14:20  风吹大风车  阅读(741)  评论(0)    收藏  举报