1、STUN协议概述
STUN(Session Traversal Utilities for NAT)NAT会话穿透工具,STUN是一个Client/Server协议,支持请求/响应类型、指示类型两种类型。STUN作为ICE(Interactive Connectivity Establishment,交互式连接建立)解决方案的一种工具使用,STUN协议本身没有穿透等能力,只是为穿透提供反射地址,穿透不成功时,需要使用TURN协议。在ICE中,STUN协议用于连通性检查和ICE的?;?。STUN具有身份验证机制,包括短期身份验证(short-term)和长期身份验证,本文就STUN中的短期身份验证进行一下详细的介绍。
2、Short-term短期身份认证
短期身份验证采用用户名/密码方式,此机制适用于单个会话。ICE使用此方法对每组连接检查应用不同的身份验证。短期身份验证机制假设在STUN事务之前,客户端和服务器已经使用了其他协议来交换了证书,以username和password形式,在WebRTC中通过SDP进行相关信息的交互,涉及ice-ufrag和ice-pwd两个属性。
证书由 username 和 password 组成,因为是短期证书,所以具有时效性,可以天然的降低重放攻击的风险。证书用于对 STUN 请求与响应消息的完整性检查,而具体的实现机制就是 HMAC,计算出的 HMAC 结果存储在 STUN 的 MESSAGE-INTEGRITY 属性中。
3、HMAC
HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code)的缩写,HMAC是一种利用密码学中的散列函数来进行消息认证的一种机制,所能提供的消息认证包括两方面内容:
消息完整性认证:能够证明消息内容在传送过程没有被修改。
信源身份认证:因为通信双方共享了认证的密钥,接收方能够认证发送该数据的信源与所宣称的一致,即能够可靠地确认接收的消息与发送的一致。
HMAC运算利用hash算法,以一个消息M和一个密钥K作为输入,生成一个定长的消息摘要作为输出。HMAC算法利用已有的Hash函数,关键问题是如何使用密钥。
4、Message Integrity计算
STUN 的 MESSAGE-INTEGRITY 属性包含了对 STUN 消息进行 HMAC-SHA1 计算之后的 HMAC 值,由于使用 SHA-1 哈希函数,所以计算出来的 HMAC 值固定为 20 字节。
4.1 HMAC输入
发送方和接收方都需要构造Message Integrity属性,接收方会比较接收的Message Integrity属性是否和计算的Message Integrity属性一致。无论发送方还是接收方关于Message Integrity的计算,其输入都遵循以下方法:
(1)STUN 消息的Message Integrity属性之前的(不包括 Message Integrity)内容,包括头部在内的所有内容作为 HMAC 的输入数据。
(2)STUN 消息的 Message Integrity属性之前的(不包括 Message Integrity),包括头部在内的所有内容的长度作为 HMAC 的输入长度。
(3)在 HMAC 计算之前,要调整 STUN 头部字段 message length 的值,message length 的大小为 Message Integrity属性之前的(包括 Message Integrity)总的长度。
关于第(3)条,需要注意的是,在构造 Message Integrity 属性时是否需要调整 message length 值的,一般是在验证 Message Integrity 属性时调整 message length 值。这是因为,对于接收方收到的 STUN 消息,可能在Message Integrity属性之后还存在 FINGERPRINT 或者 MESSAGE-INTEGRITY-SHA256 属性,因此 message length 需要去掉这两种属性的长度。然而,对于发送方,在构造 STUN 消息的 M-I 属性时,还未构造 FINGERPRINT 或者 MESSAGE-INTEGRITY-SHA256 属性,因此 message length 不需要做调整。后续会在具体的例子中进行详解。
4.2 HMAC key值
在 short-term 机制下,对于 request 发起方,HMAC 的 key 使用的是对方的 password,对于response,HMAC的key使用自己的password,即 SDP 中的 ice-pwd 描述。
5、Message Integrity示例
offer sdp
a=ice-ufrag:cVN4
a=ice-pwd:r9+6bCJUwq4RXi5lxIwTw5ww
anwser sdp
a=ice-ufrag:2g25ql32
a=ice-pwd:3s84st2o2w908951700042p58lv14084
5.1 Binding Request
原始数据:
00 01 00 50 21 12 a4 42 67 33 45 6e 4a 4b 48 56
32 43 32 7a 00 06 00 0d 32 67 32 35 71 6c 33 32
3a 63 56 4e 34 00 00 00 c0 57 00 04 00 00 03 e7
80 2a 00 08 3e e8 21 cb d9 f4 4a d7 00 24 00 04
6e 00 1e ff 00 08 00 14 ba 64 89 fa 5b 93 71 c4
d6 3d bf 20 8c a1 b2 ac 25 8b bd 75 80 28 00 04
08 39 66 23
HMAC输入:
00 01 00 48 21 12 a4 42 67 33 45 6e 4a 4b 48 56
32 43 32 7a 00 06 00 0d 32 67 32 35 71 6c 33 32
3a 63 56 4e 34 00 00 00 c0 57 00 04 00 00 03 e7
80 2a 00 08 3e e8 21 cb d9 f4 4a d7 00 24 00 04
6e 00 1e ff
HMAC key:采用对端password,即key=3s84st2o2w908951700042p58lv14084
计算HMAC-SHA1的值,与抓包一致,具体如下所示:
https://www.liavaag.org/English/SHA-Generator/HMAC
5.2 Binding Response
原始数据:
01 01 00 40 21 12 a4 42 67 33 45 6e 4a 4b 48 56
32 43 32 7a 00 06 00 0d 32 67 32 35 71 6c 33 32
3a 63 56 4e 34 00 00 00 00 20 00 08 00 01 c1 a6
8d 06 a5 0b 00 08 00 14 e5 a6 ec 84 59 fb b6 fc
41 42 07 f0 a7 71 1b 4c c7 3c 5f cf 80 28 00 04
09 21 b6 d5
HMAC输入:
01 01 00 38 21 12 a4 42 67 33 45 6e 4a 4b 48 56
32 43 32 7a 00 06 00 0d 32 67 32 35 71 6c 33 32
3a 63 56 4e 34 00 00 00 00 20 00 08 00 01 c1 a6
8d 06 a5 0b
HMAC key:采用自己password,即key=3s84st2o2w908951700042p58lv14084
输出HMAC-SHA1:
e5 a6 ec 84 59 fb b6 fc 41 42 07 f0 a7 71 1b 4c c7 3c 5f cf
6、参考
https://tools.ietf.org/html/rfc2104
https://tools.ietf.org/html/rfc5389
https://tools.ietf.org/html/rfc8489
码神说公众号:WebRTC STUN | Short-term 消息认证