探索黑客技术攻防,实战研究与安全创新

导航菜单

Android移动智能终端安全视频通信

当前正快速进入崭新的移动互联网时代,移动即时通信是厂商在移动互联网领域争夺的重点,但是与此同时,智能手机的安全性、私密性等问题逐渐引起大家的重视。本文实现了一个安全即时视频通信软件,其通过对即使通信的视频信息进行AES加密,保证了即时通信视频的的安全性和私密性。

总体设计

1.总体方案

Android智能终端安全视频通信采用客户端对客户端架构,具体模块划分如图1所示。总的来说,通过AES密钥设定,加解密模块为用户提供安全保障;通过界面模块给用户带来更好的UI和使用体验。

A57.png

图1系统架构图

2.客户端部分

1)通信模块

客户端通信模块实现视频的通信以及其他相关功能。该模块在发送数据时,从摄像头提取数据,将数据按照自定义的协议(由协议处理模块处理)进行封装,并利用UDP协议将数据传送给对方;在接收数据时,首先利用UDP协议通过socket通信接收数据,然后将数据按照自定义的协议进行解析,解析之后,将视频数据通过话筒/屏幕显示出来。

2)AES设定模块

从客户端界面输入AES密钥,通过密钥获取比较,确定通话双方会话所用的AES密钥。

3)加解密模块

客户端加解密模块用于对传输的视频信息进行端对端的加解密。需要在保证传输信息机密性的同时考虑系统工作效率,为此,我们采用了128位的AES加密算法。在每次视频之前,视频双方都会通过密钥获取比较模块来确定AES密钥。

4)UI模块

该模块为用户尽可能提供友好的人机交流UI界面,其中主要界面有:主界面、操作界面(视频操作功能)、呼叫界面(静音、免提、挂断功能)、接听界面(视频通信显示)。

1.详细操作流程

用户在打开客户端进入主界面后,输入对方的手机的ip,然后开始进行视频邀请,当接收方同意后,自动开启密钥获取比较流程进行密钥比较,在密钥比较成功后可以进行视频通话.

2.系统代码详细设计

1)输入AES密钥


privatevoidopenFirendPopup(finalStringname,finalintphoto,intflag){
Viewview=LayoutInflater.from(this).inflate(
R.layout.aesput,null);
Buttonsendase=(Button)view.findViewById(R.id.sendase);
finalAlertDialogalertDialog
=
new
AlertDialog.Builder(this).setView(view).create();
sendase.setOnClickListener(newView.OnClickListener(){
publicvoidonClick(Viewv){
if(!.equals(getaes())){
Key_Deal.setFlag(Key_Deal.VIDEO_FLAG);
MainHandler.sendRequestForVideo(name);
MainHandler.startVideoActivity(name,photo);
alertDialog.dismiss();
}}
});
if(flag==0){
sendase.setEnabled(false);
}
alertDialog.show();
}


在弹出的界面中,输入AES密钥,当输入框不为空时,点击发送按钮,则可以邀请对方开视频,然后界面消失。

2)输入AES并接受好友视频的邀请


privatevoidinitClick(){
accept.setOnClickListener(newView.OnClickListener(){
publicvoidonClick(Viewv){
if(flag==
Key_Deal.VIDEO_FLA.equals(getaes()))
{startVideoActivity();
Key_Deal.setFlag(Key_Deal.VIDEO_FLAG);
Video_Info.setIP(IP);
Voice_Info.setIP(IP);
Key_Info.setIP(IP);
}
}
});


A58.png

当点击发送按钮时,邀请好友开视频。当好友收到邀请后,输入AES密钥,点击接受,密钥比较线程则开始进行密钥比较,当双方输入的AES密钥相等时,则设定为此次双方进行视频的会话密钥。

3)密钥线程开始进行密钥获取及比较


publicstaticvoidbeginKeyThread(Stringip){
Video_Info.setIP(ip);
Key_Info.setIP(ip);
Key_InfosendInfo=newKey_Info();
sendInfo.setHead(newbyte[]{0x00});
Key_Thread.send(sendInfo);
}
publicstaticvoidsendPartOfAesOne(){
ase=FriendList_Activity.getaes();
byte[]byase1=MyKey.parseHexStr2Byte(ase);
MyKey.setAesPassword1(byase1);
MyKey.setAesKey(byase1);
Key_Infokey_Info=newKey_Info();
byte[]head=newbyte[]{0x02};
key_Info.setHead(head);
key_Info.setPartOfPassword(byase1);
Key_Thread.send(key_Info);
}
privatestaticvoiddeal0x02(byte[]password1){
MyKey.setAesPassword1(password1);
MainHandler.sendPartOfAesTwo();
MyKey.initAESKey();
}
publicstaticvoidsendPartOfAesTwo(){
ase=BeCalled_Activity.getaes();
byte[]byase2=MyKey.parseHexStr2Byte(ase);
MyKey.setAesPassword2(byase2);
Key_Infokey_Info=newKey_Info();
byte[]head=newbyte[]{0x03};
key_Info.setHead(head);
key_Info.setPartOfPassword(byase2);
Key_Thread.send(key_Info);
}
privatestaticvoiddeal0x03(byte[]password2){
MyKey.setAesPassword2(password2);
MyKey.initAESKey();
}
publicstaticvoidinitAESKey(){
if(aesPassword1.length==0aesPassword2.length==0)
return;
aes1=parseByte2HexStr(aesPassword1);
aes2=parseByte2HexStr(aesPassword2);
if(aes1.equals(aes2)){
aesKey=parseHexStr2Byte(aes1);
}
}
publicstaticStringparseByte2HexStr(bytebuf[]){
StringBuffersb=newStringBuffer();
for(inti=0;i<buf.length;i++){
Stringhex=Integer.toHexString(buf[i]0xFF);
if(hex.length()==1){
hex='0'+hex;
}
sb.append(hex.toUpperCase());
}
returnsb.toString();
}
publicstaticbyte[]parseHexStr2Byte(StringhexStr){
if(hexStr.length()<1)
returnnull;
byte[]result=newbyte[hexStr.length()/2];
for(inti=0;i<hexStr.length()/2;i++){
inthigh=Integer.parseInt(hexStr.substring(i*2,i*2+1),16);
intlow=Integer.parseInt(hexStr.substring(i*2+1,i*2+2),16);
result[i]=(byte)(high*16+low);
}
returnresult;
}


以上代码是将16进制转换为二进制,也就是将string类型转换为字节型。通信所需要的AES密钥是byte型,所以需要将从edittext中获取的string型密钥转换为byte,然后为通信进行加密。

4)AES加密


publicstaticbyte[]AESencrypt(byte[]byteContent){
if(aesKey==null)
returnnull;
try{
SecretKeySpeckey=newSecretKeySpec(aesKey,AES);
Ciphercipher=Cipher.getInstance(AES);
cipher.init(Cipher.ENCRYPT_MODE,key);
byte[]result=cipher.doFinal(byteContent);
returnresult;
}catch(NoSuchAlgorithmExceptione){
e.printStackTrace();
}catch(NoSuchPaddingExceptione){
e.printStackTrace();
}catch(InvalidKeyExceptione){
e.printStackTrace();
}catch(IllegalBlockSizeExceptione){
e.printStackTrace();
}catch(BadPaddingExceptione){
e.printStackTrace();
}
returnnull;
}


此段代码是AES加密。首先创建密码器,接着初始化,然后对将要发送出去的要加密的视频数据流内容进行加密。

5)AES解密


publicstaticbyte[]AESdecrypt(byte[]content){
if(aesKey==null)
returnnull;
try{
byte[]enCodeFormat=aesKey;
SecretKeySpeckey=newSecretKeySpec(enCodeFormat,AES);
Ciphercipher=Cipher.getInstance(AES);
cipher.init(Cipher.DECRYPT_MODE,key);
byte[]result=cipher.doFinal(content);
returnresult;
}catch(NoSuchAlgorithmExceptione){
e.printStackTrace();
}catch(NoSuchPaddingExceptione){
e.printStackTrace();
}catch(InvalidKeyExceptione){
e.printStackTrace();
}catch(IllegalBlockSizeExceptione){
e.printStackTrace();
}catch(BadPaddingExceptione){
e.printStackTrace();
}
returnnull;
}


此段代码是AES解密。先创建密码器,接着初始化,然后对从对方发送过来要解密的视频数据流内容进行解密。

3.视频加密通信测试

1)在正常“保密视频”通信的情况下,发送方使用视频之前确定的AES密钥进行加密,接收方使用AES密钥对视频数据包进行解密,可见双方能够正常进行视频通信,如图3所示。

2)在“攻击者截获视频数据包”的情况下,由于攻击者无法获取AES密钥,因而无法对视频数据包进行解密。攻击者所看到的视频信息只是毫无意义的乱码,如图4所示。

A59.png

A60.png