一、回顾SIP Register的认证过程
二、认证过程中的SIP信令(报文)
这里介绍二种查看REGISTER过程SIP信令的方法:
2.1 打开FreeSwitch的SIP trace功能
sofia profile internal siptrace on|off
在FreeSwitch控制台中,输入上面的命令行(on为打开,off为关闭),然后用Client(比如:免费开源软电话MicroSIP)注册,此时FreeSwitch中会输出4段SIP报文,分别对应认证过程中的4个阶段,类似下面这样:
第1段 REGISTER(Client → FreeSwitch)
recv 647 bytes from tcp/[10.32.26.25]:51696 at 02:14:58.914917: ------------------------------------------------------------------------ REGISTER sip:10.32.26.25:5070;transport=tcp SIP/2.0 Via: SIP/2.0/TCP 10.32.26.25:51696;rport;branch=z9hG4bKPj8d4db68b24754f539dbf3b563a44fe55;alias Max-Forwards: 70 From: <sip:1000@10.32.26.25>;tag=89aefb1f3fc0413283a453eda5407f60 To: <sip:1000@10.32.26.25> Call-ID: 1e7af0e67a5044658fc7f6716d329642 CSeq: 36850 REGISTER User-Agent: MicroSIP/3.20.3 Supported: outbound, path Contact: <sip:1000@10.32.26.25:51696;transport=TCP;ob>;reg-id=1;+sip.instance="<urn:uuid:00000000-0000-0000-0000-000011058e7e>" Expires: 300 Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS Content-Length: 0
第2段 401 Unauthorized(FreeSwitch → Client)
send 670 bytes to tcp/[10.32.26.25]:51696 at 02:14:58.918913: ------------------------------------------------------------------------ SIP/2.0 401 Unauthorized Via: SIP/2.0/TCP 10.32.26.25:51696;rport=51696;branch=z9hG4bKPj8d4db68b24754f539dbf3b563a44fe55;alias From: <sip:1000@10.32.26.25>;tag=89aefb1f3fc0413283a453eda5407f60 To: <sip:1000@10.32.26.25>;tag=Q0m1g96BS3vpa Call-ID: 1e7af0e67a5044658fc7f6716d329642 CSeq: 36850 REGISTER User-Agent: FreeSWITCH-mod_sofia/1.6.18+git~20170612T211449Z~6e79667c0a~64bit Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE Supported: timer, path, replaces WWW-Authenticate: Digest realm="10.32.26.25", nonce="bee3366b-cf59-476e-bc5e-334e0d65b386", algorithm=MD5, qop="auth" Content-Length: 0
第3段 REGISTER (第2次 Client → FreeSwitch)
recv 921 bytes from tcp/[10.32.26.25]:51696 at 02:14:58.925916: ------------------------------------------------------------------------ REGISTER sip:10.32.26.25:5070;transport=tcp SIP/2.0 Via: SIP/2.0/TCP 10.32.26.25:51696;rport;branch=z9hG4bKPj414de93b6fd34f21a9c453d81117fee2;alias Max-Forwards: 70 From: <sip:1000@10.32.26.25>;tag=89aefb1f3fc0413283a453eda5407f60 To: <sip:1000@10.32.26.25> Call-ID: 1e7af0e67a5044658fc7f6716d329642 CSeq: 36851 REGISTER User-Agent: MicroSIP/3.20.3 Supported: outbound, path Contact: <sip:1000@10.32.26.25:51696;transport=TCP;ob>;reg-id=1;+sip.instance="<urn:uuid:00000000-0000-0000-0000-000011058e7e>" Expires: 300 Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS Authorization: Digest username="1000", realm="10.32.26.25", nonce="bee3366b-cf59-476e-bc5e-334e0d65b386", uri="sip:10.32.26.25:5070;transport=tcp", response="7a8049557b2e77602625fa9ee7d8f088", algorithm=MD5, cnonce="c3606b3f70544096a7e17fcdb4670795", qop=auth, nc=00000001 Content-Length: 0
第4段 200 Ok(FreeSwitch → Client)
send 646 bytes to tcp/[10.32.26.25]:51696 at 02:14:58.933914: ------------------------------------------------------------------------ SIP/2.0 200 OK Via: SIP/2.0/TCP 10.32.26.25:51696;rport=51696;branch=z9hG4bKPj414de93b6fd34f21a9c453d81117fee2;alias From: <sip:1000@10.32.26.25>;tag=89aefb1f3fc0413283a453eda5407f60 To: <sip:1000@10.32.26.25>;tag=r9Dtj4QFpcK9N Call-ID: 1e7af0e67a5044658fc7f6716d329642 CSeq: 36851 REGISTER Contact: <sip:1000@10.32.26.25:51696;transport=TCP;ob>;expires=300 Date: Mon, 06 Sep 2021 02:14:58 GMT User-Agent: FreeSWITCH-mod_sofia/1.6.18+git~20170612T211449Z~6e79667c0a~64bit Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE Supported: timer, path, replaces Content-Length: 0
2.2 采用WireShark抓包
参考上图,启动WireShark,指定网卡以及抓包的协议为sip后,本机用Client注册登录1次,就能抓到这4个阶段的SIP信令(注:上图的REG Server是OpenSIPS),跟FreeSwith做为REG Server对比,可以发现OpenSIPS第3阶段,返回的Authorization里,少了cnounce、 qop、nc这3个值,这一点要注意一下。
三、Response Digest的计算过程
通过观察SIP报文发现,整个注册过程中Client始终没有发送过任何password的明文,相对还是很安全的。Client第2次发起REGISTER时,附带的Response值是关键!REG Server将校验这个值的正确性,校验通过才会注册成功。
整个计算过程,分成三步:
3.1 计算HA1
规则如下:
algorithm | HA1 |
---|---|
MD5(或未指定) |
MD5(username:realm:password) |
MD5-sess |
MD5(MD5(username:realm:password):nonce:cnonce) |
例1(FreeSwitch充当REG Server):
Client第2次提交的REGISTER请求中,Authorization信息为:
Authorization: Digest username="1000", realm="10.32.26.25", nonce="bee3366b-cf59-476e-bc5e-334e0d65b386", uri="sip:10.32.26.25:5070;transport=tcp", response="7a8049557b2e77602625fa9ee7d8f088", algorithm=MD5, cnonce="c3606b3f70544096a7e17fcdb4670795", qop=auth, nc=00000001
则HA1 = MD5("1000:10.32.26.25:1234") = 6a5e40ec8a6cbac75b9914b271516a47 (假设password为1234)
例2(OpenSIPS充当REG Server):
第2阶段,FreeSwitch返回的Authorization如下:
Authorization: Digest username="440444", realm="10.2.60.171", nonce="6135e48401ea0109021093850f9c5db2bf101786", uri="sip:10.2.60.171:5060", response="885f45ae2179c9d8ce2bc1cbd8e4bb9f"
则HA1 = MD5("440444:10.2.60.171:440444") = 109cf921db79c57e146cd8d46429312d (假设password与username相同,都为440444)
3.2 计算HA2
规则如下:
qop | HA2 |
---|---|
auth(或未指定) |
MD5(method:digestURI) |
auth-int |
MD5(method:digestURI:MD5(entityBody)) |
注:digestURI为SIP信令Authorization节点中的uri值,对于注册来说,method即为固定值REGISTER
例1(FreeSwitch充当REG Server):
Client第2次提交的REGISTER请求中,Authorization信息为:
Authorization: Digest username="1000", realm="10.32.26.25", nonce="bee3366b-cf59-476e-bc5e-334e0d65b386", uri="sip:10.32.26.25:5070;transport=tcp", response="7a8049557b2e77602625fa9ee7d8f088", algorithm=MD5, cnonce="c3606b3f70544096a7e17fcdb4670795", qop=auth, nc=00000001
则HA2 = MD5("REGISTER:sip:10.32.26.25:5070;transport=tcp") = c0a1637fb943febd38e69c2087d58fe9
例2(OpenSIPS充当REG Server):
第2阶段,FreeSwitch返回的Authorization如下:
Authorization: Digest username="440444", realm="10.2.60.171", nonce="6135e48401ea0109021093850f9c5db2bf101786", uri="sip:10.2.60.171:5060", response="885f45ae2179c9d8ce2bc1cbd8e4bb9f"
则HA2 = MD5("REGISTER:sip:10.2.60.171:5060") = 9f5c90dad45f8b57a9de5ad977027d7b
3.3 计算Response
根据前2步计算出来的HA1及HA2,计算response值,规则如下:
qop | response |
---|---|
未指定 |
MD5(HA1:nonce:HA2) |
auth或auth-int |
MD5(HA1:nonce:nonceCount:cnonce:qop:HA2) |
计算结果如下:
例1(FreeSwitch充当REG Server) | 例2(OpenSIPS充当REG Server) | |
---|---|---|
response |
MD5("6a5e40ec8a6cbac75b9914b271516a47:bee3366b-cf59-476e-bc5e-334e0d65b386:00000001:c3606b3f70544096a7e17fcdb4670795:auth:c0a1637fb943febd38e69c2087d58fe9") =7a8049557b2e77602625fa9ee7d8f088 |
MD5("109cf921db79c57e146cd8d46429312d:6135e48401ea0109021093850f9c5db2bf101786:9f5c90dad45f8b57a9de5ad977027d7b") =885f45ae2179c9d8ce2bc1cbd8e4bb9f |
qop | auth | 无 |
nonceCount | 00000001 | 无 |
nonce | bee3366b-cf59-476e-bc5e-334e0d65b386 | 6135e48401ea0109021093850f9c5db2bf101786 |
HA2 | c0a1637fb943febd38e69c2087d58fe9 | 9f5c90dad45f8b57a9de5ad977027d7b |
HA1 | 6a5e40ec8a6cbac75b9914b271516a47 | 109cf921db79c57e146cd8d46429312d |
cnonce | c3606b3f70544096a7e17fcdb4670795 | 无 |
参考文章:
https://en.wikipedia.org/wiki/Digest_access_authentication
https://datatracker.ietf.org/doc/html/rfc2069
https://datatracker.ietf.org/doc/html/rfc2617