Asterisk-SRTP项目总结
接到项目时,一下子就蒙了,一来对Linux系统不熟悉,二来呢,Asterisk也是相当的庞大,虽然SRTP库已经比较成熟了,但是想在Asterisk中支持SRTP,必须对SIP呼叫流程相当的清楚,对RTP传输有一定的了解。网上资料找了找,并没有比较完整的介绍Asterisk中移植SRTP代码的文章,自己经过一阶段的摸索,现在整理学习笔记如下。
原材料准备阶段:
软件 |
版本 |
下载地址 |
备注 |
Asterisk |
1.6 |
|
|
LibSRTP |
1.4.2 |
http://srtp.sourceforge.net/download.html |
|
|
|
|
|
编译LibSRTP库、测试:
解压srtp-1.4.2.tgz包到目录/home/srtp下,终端执行下面语句
cd /home/srtp
./configure
make
make install
编译成功后,便可以进行测试:
cd /home/srtp/crypto/test
./rand_gen –n 30
这时会产生一串key,如“e7b1312c9581ed2b9039232619b350f775a6148c7111d4e7b5f8a1c6c414”,复制记住这串字符,下面要用,接着执行
cd /home/srtp/test
./ rtpw -s -k e7b1312c9581ed2b9039232619b350f775a6148c7111d4e7b5f8a1c6c414 -ea 192.168.5.235 9999
-s表示发送方,ea 后面的是目标IP地址,同样在192.168.5.235上面执行上面步骤,把-s改成-r(表示接收方),这样就可以实现SRTP互相传送字符。
具体例子如下:
[sh1] set k=`test/rand_gen -n 30`
[sh1] echo $k
c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451
[sh1]$ test/rtpw -s -k $k -ea 192.168.5.235 9999
Security services: confidentiality message authentication
set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451
setting SSRC to 2078917053
sending word: A
sending word: a
sending word: aa
sending word: aal
sending word: aalii
sending word: aam
sending word: Aani
sending word: aardvark
...
[sh2] set k=c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451
[sh2]$ test/rtpw -r -k $k -ea 192.168.5.235 9999
security services: confidentiality message authentication
set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451
19 octets received from SSRC 2078917053 word: A
19 octets received from SSRC 2078917053 word: a
20 octets received from SSRC 2078917053 word: aa
21 octets received from SSRC 2078917053 word: aal
...
Asterisk中添加处理SRTP代码:
代码主要集中在chan_sip.c文件中,这里就不罗列代码了,分机一下处理过程就好了。
首先Asterisk在res文件夹中添加res_srtp.c模块,该模块主要是调用LibSRTP中的srtp_init()函数(这是调用LibSRTP首先必须执行的函数),并封装srtp创建、销毁、protect、unprotect等函数,所有srtp数据处理就都封装在这个模块里了。
其次Asterisk在rtp.c中实例化一个结构体,专门负责处理res_srtp.c中封装的函数,直接对RTP包的payload进行protect、unprotect加密或者解密,这样就完成了数据加密。
再次就是密钥的协商过程了,这个就是在chan_sip.c模块处理了,SIP话机发起呼叫Invite消息时,会在SDP中增加
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:NTkxMjA3Yjk5YmQ0ZWQzADZjZmRjM2NkNWJjODdl
这样的字段,用于告诉Asterisk这次通话要启用SRTP,采用的算法的AES_CM_128_HMAC_SHA1_80,Masterkey为inline:的内容。当Asterisk收到这样的请求,必须在process_sdp()这个函数解析a=crypto字段,当解析完成后,根据RTP的SSRC,重新创建一个crypto字符串,这个主要是调用process_crypto()函数进行处理。接着调用extensions.conf执行呼叫任务,当执行到sip_call()函数时,需要判断所要呼叫分机是否启用了SRTP,如果该分机开启SRTP功能,必须在sip_call()函数中再次创建为呼叫该分机所需要的SRTP密钥。呼叫方与被呼叫方,都的在200OK消息时,收到对应的密钥,这样就完成了SRTP协商过程。简单流程如下:
配置文件修改:
修改Asterisk目录下的configure文件,增加SRTP配置。这个会比较多,如果有需要再向我要。如果./configure成功的话,会在文件makeopts增加
SRTP_INCLUDE=
SRTP_LIB= -lsrtp
在文件makeopts.in增加
SRTP_INCLUDE=@SRTP_INCLUDE@
SRTP_LIB=@SRTP_LIB@
会在built_tools文件夹底下的menuselect-deps中添加
SRTP=1:1
在文件menuselect-deps.in中添加
SRTP=@PBX_SRTP@
这样的话配置完成。
呼叫计划与分机属性设置:
在呼叫分机的地方增加
exten = s,n,Set(_SIPSRTP=${SIPPEER(${EXTEN},srtpcapable)})EXTEN为sip_call()函数所要呼叫的分机号码如502
在502分机属性中增加srtpcapable=yes,同时要启用502分机的SRTP支持。
编译、运行Asterisk与测试:
。。。。。。