发明内容
本发明的目的是解决现有技术的安全问题,通过基于Android系统的移动终端进行安全VoIP(Voice over Internet Protocol)会话,使得在RTP通路建立之前,即SIP(Session Initiation Protocol,会话初始协议)会话协商部分进行通话双方的密钥协商和身份认证,并且基于ERTP协议,实现通话语音数据的端到端加密功能,达到通信保密的目的。
本发明的原理为:通过对SIP媒体栈进行改进,并结合SIP协议来完成包含DSA数字签名的D-H(Diffie-Hellman)密钥交换协议,协商会话密钥并对会话双方进行身份认证,做到一次一密且抗中间人攻击。会话部分使用128位密钥的AES(Advanced EncryptionStandard)算法对语音数据进行加密。当主叫用户使用加密会话模式呼叫被叫时,提示被叫采用加密模式通信。如果被叫同样采用加密模式,则进行密钥协商;如果被叫方拒绝加密会话模式,则通过弹出对话框的方式向主叫方提示会话未被加密,并挂断电话。
当被叫接受会话邀请后,通话建立,双方的语音数据经过DSA(Digital SignatureAlgorithm) 数字签名后,使用协商好的密钥进行加密后传送给对方。当对方收到数据后先进行解密,然后进行DSA签名验证操作。
本发明的功能实现基于动态链接库完成,界面操作及人机交互部分在Android系统中的Java程序框架层完成,两者依靠JNI(Java Native Interface,Java本地调用)模块进行通信。
本发明提出的面向Android系统移动终端语音端到端加密方法包括以下步骤:
1)用户注册:主叫和被叫用户在服务器注册,包括注册请求和服务器认证两个步骤。注册完成后,用户可以用注册账号完成SIP电话的通信。
2)发起呼叫:主叫用户使用加密会话模式发起呼叫,向服务器发起会话邀请。服务器确认用户已通过认证后,检查Via头域,若没有问题插入自身地址,并向Invite消息的To域所指示的被叫终端代理转送Invite请求。该部分内容通过Java程序框架层与动态链接库间的通信来实现。
3)密钥协商:主叫方与被叫方通过SIP协议进行会话协商。在会话协商的同时双方进行D-H交换,协商会话密钥并对会话双方进行身份认证。密钥协商过程依靠动态链接库实现。
4)会话建立:被叫接受呼叫,密钥协商完成,则通话建立。
5)加密通信:使用协商好的公钥进行签名,然后利用会话密钥加密发送给对端。通话双方使用协商好的会话密钥,利用AES算法对会话内容进行端到端的加解密, 以达到防止篡改的目的。加密语音通信过程由动态链接库进行功能实现。
6)会话结束:通信双方结束会话,本次会话密钥清零。
密钥协商包含身份认证和会话密钥协商两个部分。通过密钥协商,达到安全协商并计算本次通话会话密钥的目的。其实现的方法:
1)身份认证:采用双向认证,会话双方使用各自的ID进行认证,保证消息来源于本人且未被篡改。当用户作为主叫用户发起会话时,服务器会将被叫用户的公钥发送给主叫用户,并向被叫用户发送主叫用户的公钥。主叫用户与被叫用户在通话时利用自己的私钥,对所发送的信息进行DSA签名。
2)会话密钥协商:使用D-H交换,在利用对方的公钥对发送的内容进行加密的情况下,通过两次交互完成会话密钥的协商,并在公钥后附上一个随机数。两次交互后,主叫方回复被叫发送的随机数,表示密钥协商完成。
所述加密通信包括DSA数字签名、语音加密、语音解密和DSA签名验证四个方法,具体实现为:
1)DSA数字签名:对于生成的语音数据,用协商好的自身私钥对语音数据进行签名,然后将语音帧连同签名一起封装到RTP包中。对于收到的语音帧,验证其签名,若符合则继续进行解码,若不符合则丢弃。
2)语音加密:包括RTP包的提取、RTP包加密、封装成UDP包三个步骤。语音经过采样编码后以语音帧的格式封装到RTP包中。语音加密时,将RTP包提取出来,然后对RTP包进行加密。加密后的包则封装到UDP包内,进行网络传输。
3)语音解密:包括UDP包解封装、RTP包解密、DSA签名验证三个步骤。接收端对UDP包解封后,取出载有语音数据的RTP包,对其解密后再进行DSA签名的验证。
4)DSA签名验证:对接收到的解密后的数据,用户使用对方公钥进行DSA签名验证。若验证结果相符,则继续对RTP包操作;若不符,则丢弃该包。
采用了上述技术方案后,本发明提供了一种面向Android系统移动终端的语音端到端加密方法,该方法通过软件实现了移动终端VoIP电话的语音加密功能。在用户完成SIP注册之后,发起呼叫,在被叫接听之前完成双方密钥协商和身份认证。会话建立后,载有通信语音的RTP包首先经过自身私钥DSA签名,再使用协商好的密钥进行AES加密后传递。在接收端接收到语音包后,解密恢复出语音包,使用对方公钥验证DSA签名的有效性后再送回缓冲区。本发明提供的基于ERTP包的加密方式,与现有的加密方式相比,语音加密算法是基于RTP包的,不需要额外引入协议支持,具有开销小,可移植性高,易于实现的特点。其中密钥协商过程可以在信令部分进行会话协商的同时完成。本发明无需额外硬件支持,也不需要对服务器进行调整。此外用户界面友好,易于操作。
具体实现方式
图1所示为本发明的应用场景,本发明主要用于可以进行SIP通话的Android系统手机。首先,用户完成服务器注册。当服务器注册完成后,若用户需要进行加密通话,则摘机拨号,并选择使用加密模式发起呼叫102。在会话初始阶段,双方使用SIP进行会话初始协商,并同时完成身份认证301及会话密钥协商302过程。身份认证301过程使用用户ID进行双向认证:若身份认证301成功,则进行会话密钥协商302;若不成功,则返回身份认证301失败错误。在会话密钥协商302过程中,若协商不成功,则通话结束并返回错误;若协商成功,则用户保存各自的私钥X、对方的公钥Y以及本次会话密钥KS。在协商完成后,会话建立,首先进行初始化,然后通信双方进行加密的语音通信。对于发送的载有语音数据的RTP包,首先使用本人的私钥X进行DSA数字签名,然后使用协商好的会话密钥KS进行AES加密,再封装成UDP包传输;对于收到的UDP包,先解封装,使用会话密钥KS解密后,再进行签名验证。若验证成功,则取出该RTP包;若不成功,则丢弃该包。当会话结束后,本次会话密钥清零604。
图2所示为本发明的软件结构框图。本发明的软件结构主要由三个部分组成:Java程序框架、JNI模块及动态链接库。
1)Java程序框架是针对Android操作系统开发的程序架构,包括UI界面、Utility设备、API接口、Service服务、DB数据库、SIP协议栈、Widget外观、Model模型及Wizard向导九个部分。UI界面是本发明软件在终端操作系统的操作界面设计;Utility设备针对拨号键盘、手机听筒等设备进行调用;API接口用来进行媒体层的状态描述及配置管理等内容,Service服务管理后台运行和跨进程访问;DB数据库用来存储联系人、手机信息等内容;SIP协议栈在Java程序框架内实现动态链接库;Widget外观为程序提供皮肤管理;Model模型对数据库进行操作;Wizard向导是软件提供给用户的操作提示。
2)JNI模块定义了一套接口,当标准的Java程序框架不支持程序所需的特性时,供Java程序框架和动态链接库之间进行相互调用。
3)动态链接库是对Java程序框架的功能支持,对程序的基本功能进行实现,包括声音器件库、SIP协议栈JNI库和音频编码库。声音器件库用来实现对硬件设备的调用;SIP协议栈JNI库用来实现协议栈的功能及与Java程序框架的相互调用和通信;音频编码库用来实现VoIP软件电话的宽带音频编解码。
图3所示为本发明的端到端语音加解密流程图。主要包括用户注册101、使用加密模式发起呼叫102、密钥协商103、会话建立104、加密通话105、通话结束106六个步骤:
1)用户注册101:用户向服务器发送注册请求。若数据库中未包含用户信息,则返回质询信息。终端提示用户输入其标识和密码后,向服务器发送该消息。服务器验证其合法性后,将用户信息写入数据库中。
2)使用加密模式发起呼叫102:主叫用户完成注册后,选择使用加密模式对被叫用户发起呼叫;否则使用正常模式发起呼叫。在Android系统的Java程序框架层完成人机交互,随后将得到的结果通过JNI模块传到动态链接库。
3)密钥协商103:双方使用SIP协议进行会话初始协商的同时进行身份认证301及会话密钥协商302。若身份认证301成功,则进行会话密钥协商302;若不成功,则返回身份认证301失败错误。若会话密钥协商302不成功,则通话结束并返回错误。若会话密钥协商302成功,则会话建立104。该部分在动态链接库中进行功能实现。
4)会话建立104:终端收到确认会话的消息后,存储本次会话密钥401。在对缓冲区初始化402、参数及定时器初始化403和启动声音器件404后,会话建立104完成。
5)加密通话105:呼叫连接建立后,通信双方使用自己的私钥对载有语音数据的RTP包进行签名,之后用协商好的会话密钥对RTP包及签名进行加密。对方收到数据包后,首先对加密好的数据包进行解密,然后比对发送的RTP包和签名是否一致。若一致,则取出RTP包,进行进一步操作。该步骤在动态链接库中进行功能实现。
6)通话结束106:通信双方当中一方挂断电话,呼叫释放603,本次会话密钥清零604。
图4所示为使用加密模式发起呼叫的流程图,其主要步骤如下:
1)用户拨号201:用户作为主叫发起通话。
2)选择通话模式202:当发起呼叫时,用户首先进行模式选择:加密模式或非加密模式,在Android系统的应用框架层完成用户与终端的交互。随后将得到的结果通过JNI模块传到动态链接库。
3)加密模式初始化203:终端调用动态链接库,判断是否使用加密模式。若为加密模式,则进行加密模式初始化,加密状态置1,并提示被叫采用加密模式通信204;若选择普通模式,加密状态置0,则进行普通模式初始化,用户进行正常的语音通话。
4)提示被叫采用加密模式通信204:被叫若同意使用加密模式,则双方进行密钥协商;若不同意使用加密模式,则通过弹出对话框的方式向主叫方提示会话未被加密,则本次通话挂断。被叫用户的加密模式判断在Java程序框架层完成,之后把结果同样通过JNI模块传到动态链接库,进行配置及调用;主叫用户提示:本次通话未加密,则是由动态链接库将状态上传到JNI模块,然后在界面给出提示的。
图5所示为密钥协商103的流程图。首先,会话双方进行双向的身份认证301,若身份认证301不成功,则呼叫结束并返回错误:身份认证301失败。若身份认证301成功,则会话双方进行密钥协商302。若协商不成功,则呼叫结束并返回错误:会话密钥协商302失败;若会话密钥协商302成功,则会话建立104。该步骤的内容在动态链接库进行功能实现。
图6所示为密钥协商的具体实现交互图,包含以下步骤:
1)用户A发起呼叫,取随机数XA作为自己的私钥,计算公钥,其中p为公开的长度在512到1024之间的素数,α为其本原根。A向被叫B发送Invite请求,同时在SDP(Session Description Protocol,会话描述协议)部分向对方发送用固定密钥Kfixed 进行AES加密的公钥YA、身份信息IDA和随机数N1,即发送Invite||E(Kfixed,YA||IDA||N1)。服务器收到后确认用户认证301已通过后,检查请求中的Via头域中是否已包含其地址:若已包含,说明发生环回,则返回错误应答;若不包含,则服务器在请求的Via头域插入自身地址,修改Invite请求为Invite',并转发该消息,即向B用户发送Invite'||E(Kfixed,YA||IDA||N1)。然后服务器向终端A发送呼叫处理中的应答消息:100Trying。
2)终端B在收到转发消息Invite'||E(Kfixed,YA||IDA||N1)后,验证终端A的身份信息IDA与From头域的是否吻合,并保存公钥YA和随机数N1,然后向服务器发送呼叫处理中的应答消息:100Trying。
3)终端B指示被叫用户振铃,振铃后,终端B向服务器发送振铃消息:180Ringing。服务器向终端A转发该振铃消息:180Ringing。
4)被叫用户摘机,终端B取随机数XB作为自己的私钥,计算公钥和本次会话密钥。终端B向服务器返回表示连接成功的应答200OK,并在SDP中包含固定密钥Kfixed加密的公钥YB、身份信息IDB、终端A发送的随机数N1及自己产生的随机数N2,即发送200OK||E(Kfixed,YB||IDB||N1||N2)。服务器向终端A转发该成功指示。
5)终端A收到消息后,检验终端B的身份信息IDB与From头域的是否吻合,并检查N1是否正确。若条件都满足,则保存随机数N2,计算本次会话密钥;否则返回错误:会话密钥协商302失败。由于KS=KS',所以双方得到的会话密钥相同。
6)终端A向服务器发送确认消息ACK和用固定密钥Kfixed加密的随机数N2,即发送ACK||E(Kfixed,N2)。代理服务器将该确认消息转发给终端B。终端B检查随机数N2的正确性:若正确,则主被叫用户之间建立通信连接,开始通话;若不正确,则返回错误:会话密钥协商302失败。
图7所示为会话建立104的流程图。当被叫收到会话确认信息ACK后,会话建立,会话双方存储本次会话密钥401,然后对缓冲区初始化402、参数及定时器初始化403、启动声音器件404。
图8所示为语音通信105的流程图。声音首先经过声音器件后采样为语音数据(声音器件处理501),然后对数据进行PCM编码(编码/解码502),将语音数据封装成RTP包(RTP包封装/解封503)后,用自己的私钥对RTP包生成DSA数字签名(DSA数字签名/签名验证504)。之后使用协商好的会话密钥,对整个包进行AES加密(RTP包加密/解密505)后,再嵌到UDP包中(UDP包封装/解封506),最后进行发送。接收UDP包后的流程则反过来。在终端收到UDP包后,先对UDP包解封(UDP包封装/解封506),使用会话密钥对加密过的RTP包进行AES解密(RTP包加密/解密505),之后DSA签名验证(DSA数字签名/签名验证504):比对用明文及公钥生成的DSA数字签名与发送来的DSA数字签名:若不相同则证明包内容受到篡改,丢弃该RTP包;若匹配,则对RTP包进行解封(RTP包封装/解封503),将语音数据解码(编码/解码502)后送到声音器件,最后用扬声器播放(声音器件处理501)出来。该部分内容在动态链接库中进行功能实现。
图9所示为DSA数字签名的计算图。在终端获取到RTP包rtp_pkt后,选择一个长度160位的素数q,且满足q能够整除(p-1);选择g满足g=h(p-1)/qmodq,其中h是1到p-1之间的整数使得g大于1;产生随机数k,计算与,其中,函数H(rtp_pkt)生成了RTP包rtp_pkt的消息散列码。最后,将得到的DSA签名(r,s)附在RTP包rtp_pkt后,即生成签名后的RTP包rtp_pkt||(r,s)。
图10所示为RTP包加密的具体实现方法。使用协商好的128bit会话密钥KS,对封装好的RTP包rtp_pkt与其生成的签名(r,s)进行AES算法加密,即得到E{KS,rtp_pkt||(r,s)}。然后将加密后的密文输出E{KS,rtp_pkt||(r,s)}嵌入UDP包,进行传输。
图11所示为RTP包解密的计算图。使用协商好的128bit的会话密钥KS,对收到的加密的RTP包rtp_pkt'与(r',s')进行AES算法解密,即对E{KS,rtp_pkt'||(r',s')}解密。然后对解密后的明文输出rtp_pkt'||(r',s')进行DSA数字签名验证。
图12所示为DSA签名验证的计算图。解密后,取出收到的附DSA数字签名的RTP包,进行DSA签名验证。计算,,,。检验v是否等于r':若等于,则DSA签名验证成功,取出rtp_pkt';若不等于,则丢弃该包。
图13所示为通话结束106的流程图。当会话双方通话结束时,一方挂断,发送挂断请求Bye601。对端请求回复200OK602后,呼叫释放603,本次会话密钥清零604。