一、 基本原理
本方案规定的加解密所处的网络位置在OSI网络体系结构的第五层,加密的内容是TCP/UDP的负载,VoIP信令结构也属于被加密的内容。
在发送端,把输入内容按数据位排列成矩阵,按照协商的方式和密钥形成一个列加密矩阵、行加密矩阵和加扰矩阵,用列加密矩阵对输入数据的列进行数据位交换,用行加密矩阵对输入数据的行进行数据位交换,用加扰矩阵对数据块按字节进行异或操作,从而达到加密的目的。在接收端,使用同样三个矩阵的逆矩阵顺序进行去扰、行恢复和列恢复,还原出原始数据。
在整个加解密过程中,我们仅仅使用数据位交换和异或操作,于是我们把这种加密方法命名位BEEO,英文字母取自单词Bit-Exchange和Exclusive-OR。
为了计算简单而且保证输入输出的数据长度完全一样,我们建议使用8行×N列矩阵,这样,每个字节对应于矩阵的一列,顺序排列形成矩阵。
我们使用密钥交换算法产生一个属于通讯双方共有的6个私有数值,三个作为密钥,与公共密钥一起计算一个三个HASH数字签名;剩余三个作为矩阵生成偏移量;把数字签名根据矩阵生成偏移量进行循环移位,生成列交换矩阵、行交换矩阵和加扰矩阵。
加密矩阵生成方式很多,一般情况下,我们建议选用8行×32列共计128位的加密矩阵;采用DH(Diffie-Hellman)算法完成密钥交换,并选择密钥和矩阵生成偏移量的DH特征值长度分别为160位和16位;选择MD5产生HASH数字签名,数字签名长度为128位;
二、 DH交换
DH交换的目的在于以明文的方式交换密钥特征,形成只有参与通讯的双方才知道而且通讯双方一定知道的私有数值。
确定一个模数(如p)以及底数(如g);两个通讯设备(如MA、MB)各随即选取一个加密指数(如a和b),以明文方式报告自己的DH特征值(如A和B),然后各自进行乘幂计算以产生这个私有数值:

通讯双方选择的加密指数是不公开的,应该相对较大,而且应该通过某种随即算法保证这个加密指数是变化的。其次,通讯双方每隔一定时间,应该申请更改私有密钥,以避免黑客获得太多的数据样本并破译通讯内容。
针对基本原理中提到的各个特征数据的长度,我们规定,用于生成密钥的加密指数至少应该达到12位,用于生成偏移量的加密指数建议选择8位,这样,六个加密指数的选择空间总和至少达到60位。
一般情况下,在客户端登录以前,客户端向服务器端发起DH交换请求报文,报告自己的6个DH特征值,服务器端收到请求以后,向用户发送自己的6个DH特征值,双方分别使用对方的DH特征值和自身的加密指数计算出私有密钥并生成最终的加密矩阵。虽然这一组报文是以明文方式传输的,但即便黑客得到了这些明文,也知道整套算法的所有细节,黑客也不足以形成这个私有密钥,这是使用DH交换的基本出发点。
对于媒体传输,通讯双方并不存在客户端和服务器的区分,这时我们要求,在通过信令完成RTP参数交换以后,双方各自在第一时刻发起DH交换请求,而且任何一方收到DH交换请求以后,立即向用户发送自己的DH特征值,从而建立起这个加密信道。
这里需要重点阐述一下加密指数。我们要求设备产生的加密指数是随机的、变化的,而且6个加密指数之间没有任何的联系。事实上,某些嵌入式设备根本不能产生随机数,当程序运行到某一条指令的时候,时钟是一个固定值,随机算法的种子是一个固定值,甚至各个寄存器也是一个固定值,用随机算法产生的下一个数据也是固定值。而对于PC环境,虽然时钟是变化的,有可能获得一个真正随机的种子,但使用rand()等函数获得的伪随机序列其实是一个固定序列。在程序启动的时候以及运行过程中,最好读一小段语音数据或者网路数据,以这些数据进行运算和组合,形成加密指数。
三、 程序接口
这里,我们仅仅给出基于UDP实现的相关协议(包括MGCP的全部信令、SIP的全部信令、H.323的部分信令、RTP媒体、RTCP媒体控制)的接口,而基于TCP实现的相关协议(H.323的部分协议)的接口将在其他文档中给出。
对于UDP传输,一般情况下,我们在每个设备上建立一个加密参数索引表,根据UDP发送端口、UDP接收端口和UDP接收地址(IP地址)进行索引。每次发送的时候,检查DH交换是否完成,如果没有完成,则主动放弃这个报文的发送,并发送DH交换请求报文;如果已经完成,则加密以后发送出去;每次接收的时候,检查DH交换是否完成,如果没有完成,检查这个报文是否为DH交换报文,尝试完成DH交换,并计算位交换矩阵和异或矩阵;如果已经完成,则按照DH交换报文特征进行过滤以后报告给应用程序。当然,在这个过程中,任何一个设备可以随时启动对任何一个连接的再次DH交换,并且在某个连接空闲一段时间以后关闭这个连接。
(在交换报文中,我们还需要定义一个叫做报文序号的变量,并强制规定这个需要不能为0。每个设备自行管理属于自己的报文序号。在发送交换报文的时候,设备应该把自己的报文序号和已经收到的对方的报文序号发送给对方;另外一方根据接收到的报文序号判断协商是否完成,或者是否开始了一次新的交换过程)
(这样实现,必然会丢弃信道建立初期的一到两个信令单元,但我们可以相信这并不会影响VoIP的实现。因为在SIP或者MGCP或者H.323的UDP信令传输过程中,已经通过重传报文规避了丢包风险;而RTP传输中,信道建立初期丢失几个报文几乎不会影响通讯质量。如果确实不允许丢弃报文,我们可以开辟少量的缓存空间,把这些报文保存下来,一旦DH交换完成,再把这些报文发送出去。)
我们重载操作系统中原来的UDP收发函数(一般命名为sendto、recvfrom或其他类似字样),把发送函数定义成BEEO_sendto,把接收函数定义成BEEO_recvfrom,而接口函数中各个参数的定义完全相同于实际操作系统中相应函数的参数定义。这两个函数就是最基本的程序接口。
一、 基本原理
本方案规定的加解密所处的网络位置在OSI网络体系结构的第五层,加密的内容是TCP/UDP的负载,VoIP信令结构也属于被加密的内容。
在发送端,把输入内容按数据位排列成矩阵,按照协商的方式和密钥形成一个列加密矩阵、行加密矩阵和加扰矩阵,用列加密矩阵对输入数据的列进行数据位交换,用行加密矩阵对输入数据的行进行数据位交换,用加扰矩阵对数据块按字节进行异或操作,从而达到加密的目的。在接收端,使用同样三个矩阵的逆矩阵顺序进行去扰、行恢复和列恢复,还原出原始数据。
在整个加解密过程中,我们仅仅使用数据位交换和异或操作,于是我们把这种加密方法命名位BEEO,英文字母取自单词Bit-Exchange和Exclusive-OR。
为了计算简单而且保证输入输出的数据长度完全一样,我们建议使用8行×N列矩阵,这样,每个字节对应于矩阵的一列,顺序排列形成矩阵。
我们使用密钥交换算法产生一个属于通讯双方共有的6个私有数值,三个作为密钥,与公共密钥一起计算一个三个HASH数字签名;剩余三个作为矩阵生成偏移量;把数字签名根据矩阵生成偏移量进行循环移位,生成列交换矩阵、行交换矩阵和加扰矩阵。
加密矩阵生成方式很多,一般情况下,我们建议选用8行×32列共计128位的加密矩阵;采用DH(Diffie-Hellman)算法完成密钥交换,并选择密钥和矩阵生成偏移量的DH特征值长度分别为160位和16位;选择MD5产生HASH数字签名,数字签名长度为128位;
二、 DH交换
DH交换的目的在于以明文的方式交换密钥特征,形成只有参与通讯的双方才知道而且通讯双方一定知道的私有数值。
确定一个模数(如p)以及底数(如g);两个通讯设备(如MA、MB)各随即选取一个加密指数(如a和b),以明文方式报告自己的DH特征值(如A和B),然后各自进行乘幂计算以产生这个私有数值:

通讯双方选择的加密指数是不公开的,应该相对较大,而且应该通过某种随即算法保证这个加密指数是变化的。其次,通讯双方每隔一定时间,应该申请更改私有密钥,以避免黑客获得太多的数据样本并破译通讯内容。
针对基本原理中提到的各个特征数据的长度,我们规定,用于生成密钥的加密指数至少应该达到12位,用于生成偏移量的加密指数建议选择8位,这样,六个加密指数的选择空间总和至少达到60位。
一般情况下,在客户端登录以前,客户端向服务器端发起DH交换请求报文,报告自己的6个DH特征值,服务器端收到请求以后,向用户发送自己的6个DH特征值,双方分别使用对方的DH特征值和自身的加密指数计算出私有密钥并生成最终的加密矩阵。虽然这一组报文是以明文方式传输的,但即便黑客得到了这些明文,也知道整套算法的所有细节,黑客也不足以形成这个私有密钥,这是使用DH交换的基本出发点。
对于媒体传输,通讯双方并不存在客户端和服务器的区分,这时我们要求,在通过信令完成RTP参数交换以后,双方各自在第一时刻发起DH交换请求,而且任何一方收到DH交换请求以后,立即向用户发送自己的DH特征值,从而建立起这个加密信道。
这里需要重点阐述一下加密指数。我们要求设备产生的加密指数是随机的、变化的,而且6个加密指数之间没有任何的联系。事实上,某些嵌入式设备根本不能产生随机数,当程序运行到某一条指令的时候,时钟是一个固定值,随机算法的种子是一个固定值,甚至各个寄存器也是一个固定值,用随机算法产生的下一个数据也是固定值。而对于PC环境,虽然时钟是变化的,有可能获得一个真正随机的种子,但使用rand()等函数获得的伪随机序列其实是一个固定序列。在程序启动的时候以及运行过程中,最好读一小段语音数据或者网路数据,以这些数据进行运算和组合,形成加密指数。
三、 程序接口
这里,我们仅仅给出基于UDP实现的相关协议(包括MGCP的全部信令、SIP的全部信令、H.323的部分信令、RTP媒体、RTCP媒体控制)的接口,而基于TCP实现的相关协议(H.323的部分协议)的接口将在其他文档中给出。
对于UDP传输,一般情况下,我们在每个设备上建立一个加密参数索引表,根据UDP发送端口、UDP接收端口和UDP接收地址(IP地址)进行索引。每次发送的时候,检查DH交换是否完成,如果没有完成,则主动放弃这个报文的发送,并发送DH交换请求报文;如果已经完成,则加密以后发送出去;每次接收的时候,检查DH交换是否完成,如果没有完成,检查这个报文是否为DH交换报文,尝试完成DH交换,并计算位交换矩阵和异或矩阵;如果已经完成,则按照DH交换报文特征进行过滤以后报告给应用程序。当然,在这个过程中,任何一个设备可以随时启动对任何一个连接的再次DH交换,并且在某个连接空闲一段时间以后关闭这个连接。
(在交换报文中,我们还需要定义一个叫做报文序号的变量,并强制规定这个需要不能为0。每个设备自行管理属于自己的报文序号。在发送交换报文的时候,设备应该把自己的报文序号和已经收到的对方的报文序号发送给对方;另外一方根据接收到的报文序号判断协商是否完成,或者是否开始了一次新的交换过程)
(这样实现,必然会丢弃信道建立初期的一到两个信令单元,但我们可以相信这并不会影响VoIP的实现。因为在SIP或者MGCP或者H.323的UDP信令传输过程中,已经通过重传报文规避了丢包风险;而RTP传输中,信道建立初期丢失几个报文几乎不会影响通讯质量。如果确实不允许丢弃报文,我们可以开辟少量的缓存空间,把这些报文保存下来,一旦DH交换完成,再把这些报文发送出去。)
我们重载操作系统中原来的UDP收发函数(一般命名为sendto、recvfrom或其他类似字样),把发送函数定义成BEEO_sendto,把接收函数定义成BEEO_recvfrom,而接口函数中各个参数的定义完全相同于实际操作系统中相应函数的参数定义。这两个函数就是最基本的程序接口。
