Asterisk-SRTP项目总结 接到项目时,一下子就蒙了,一来对Linux系统不熟悉,二来呢,Asterisk也是相当的庞大,虽然SRTP库已经比较成熟了,但是想在Asterisk中支持SRTP,必须对SIP呼叫流程相当的清楚,对RTP传输有一定的了解。网上资料找了找,并没有比较完整的介绍Asterisk中移植SRTP代码的文章,自己经过一阶段的摸索,现在整理学习笔记如下。 原材料准备阶段:
编译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与测试: 。。。。。。 |