TCP传输中使用AES加密和gizp压缩

最近项目需求需要用到TCP传输,为了保证安全传输使用AES,为了使 传输过程中减 数据量小,使用gzip压缩,特此分享一哈。
一、AES加密
关于AES的资料网上很多,个人觉得《加密与解密(第三版)》很不错,这本书中P155开始讲AES 下载地址: http://download.csdn.net/detail/qiwenmingshiwo/8755683
这个过程中我们使用 bcprov 这个jar包,官网: http://www.bouncycastle.org/
1. 我们秘钥的定义:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
publicfinalstaticCipherParameterskeyParams1=newParametersWithIV(
newKeyParameter(newbyte[]{(byte)0x01,(byte)0x01,
(byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01,
(byte)0x01,(byte)0x01,(byte)0xab,(byte)0x01,
(byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01,
(byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01,
(byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01,
(byte)0x01,(byte)0xfc,(byte)0x01,(byte)0x01,
(byte)0x01,(byte)0xed,(byte)0x01,(byte)0x01,
(byte)0x01,(byte)0x01}),newbyte[]{(byte)0x01,
(byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01,
(byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01,
(byte)0x01,(byte)0x01,(byte)0x01,(byte)0x01,
(byte)0x01,(byte)0xcf,(byte)0x01});
2.加密方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
*AES加密
*@paramdata数据
*@return
*@throwsInvalidCipherTextException
*/
publicstaticbyte[]encrypt(byte[]data)throwsInvalidCipherTextException
{
BufferedBlockCiphercipher=newPaddedBufferedBlockCipher(newCBCBlockCipher(newAESEngine()));
cipher.init(true, keyParams);//秘钥
byte[]encrypt=newbyte[cipher.getOutputSize(data.length)];
intsize=cipher.processBytes(data,0,data.length,encrypt,0);
byte[]encrypted=newbyte[size+cipher.doFinal(encrypt,size)];
System.arraycopy(encrypt,0,encrypted,0,encrypted.length);
returnencrypted;
}

二、AES解密
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
*AES解密
*@paramdata数据
*@return
*@throwsInvalidCipherTextException
*/
publicstaticbyte[]decrypt(byte[]data)throwsInvalidCipherTextException
{
BufferedBlockCiphercipher=newPaddedBufferedBlockCipher(newCBCBlockCipher(newAESEngine()));
cipher.init(false, keyParams);//
byte[]decrypt=newbyte[cipher.getOutputSize(data.length)];
intlength=cipher.processBytes(data,0,data.length,decrypt,0);
byte[]decrypted=newbyte[length+cipher.doFinal(decrypt,length)];
System.arraycopy(decrypt,0,decrypted,0,decrypted.length);
returndecrypted;
}

三、Gizp压缩和解压缩
这一个部分网上有很多,比如下面这个大神的。
Java压缩技术(四) GZIP——Java原生实现
1. 压缩
    1. /**
    2. *数据压缩
    3. *
    4. *@paramis
    5. *@paramos
    6. *@throwsException
    7. */
    8. publicstaticvoidcompress(InputStreamis,OutputStreamos)
    9. throwsException{
    10. GZIPOutputStreamgos=newGZIPOutputStream(os);
    11. intcount;
    12. bytedata[]=newbyte[BUFFER];
    13. while((count=is.read(data,0,BUFFER))!=-1){
    14. gos.write(data,0,count);
    15. }
    16. gos.finish();
    17. gos.flush();
    18. gos.close();
    19. }

2.解压缩
  1. /**
  2. *数据解压缩
  3. *
  4. *@paramis
  5. *@paramos
  6. *@throwsException
  7. */
  8. publicstaticvoiddecompress(InputStreamis,OutputStreamos)
  9. throwsException{
  10. GZIPInputStreamgis=newGZIPInputStream(is);
  11. intcount;
  12. bytedata[]=newbyte[BUFFER];
  13. while((count=gis.read(data,0,BUFFER))!=-1){
  14. os.write(data,0,count);
  15. }
  16. gis.close();
  17. }

四、简单示例
我们创建一个java程序模拟后台,创建一个android程序当做客户端。

1.后台(java控制台程序模拟)
主程序部分
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/**
*@authorxiaoming
*@time2015年5月30日下午5:01:01
*@说明AesDemo
*/
publicclassAesDemo{
publicstaticvoidmain(String[]args){
test();
}
publicstaticvoidtest(){
ServerSocketss=null;
Sockets=null;
DataInputStreamdis=null;
DataOutputStreamdos=null;
try{
ss=newServerSocket(10000);
s=ss.accept();
//========================获取请求部分==========================
dis=newDataInputStream(s.getInputStream());
//读取数据
byte[]recData=(newTcpUtil()).readData(dis);
System.out.println("长度:"+recData.length);
解压缩
byte[]uncompress=GZipUtils.decompress(recData);
//解密
byte[]decrypt=AESUtil.decrypt(uncompress);
System.out.println("解密前:"+newString(uncompress));
System.out.println("解密后:"+newString(decrypt));
//======================响应部分================================
dos=newDataOutputStream(s.getOutputStream());
byte[]respData="傻逼傻逼蹦擦擦".getBytes();
//加密
byte[]encrypt=AESUtil.encrypt(respData);
压缩
byte[]compress=GZipUtils.compress(encrypt);
dos.writeInt(compress.length);//把数据的长度写过去
dos.write(compress);
dos.flush();
s.shutdownOutput();
}catch(InvalidCipherTextExceptione){
e.printStackTrace();
}catch(IOExceptione){
e.printStackTrace();
}catch(Exceptione){
e.printStackTrace();
}finally{
try{
//关闭资源
if(dis!=null){
dis.close();
}
if(dos!=null){
dos.close();
}
if(s!=null){
s.close();
}
if(ss!=null){
ss.close();
}
}catch(IOExceptione){
e.printStackTrace();
}
}
}
}

上面读取数据时候使用的: byte []recData=( new TcpUtil()).readData(dis);进行了封装。TcpUtil类如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
*@authorqiwenming
*@time2015年5月30日下午4:16:45
*@说明Tcp请求的工具类简单的实现一哈
*/
publicclassTcpUtil{
/**
*读取数据
*@throwsIOException
*/
publicstaticbyte[]readData(DataInputStreamdis)throwsIOException{
//数据的长度
intlength=dis.readInt();
inttmpLength=1024;//每次读取最大缓冲区大小
byte[]ret=newbyte[length];//读取到流
intreaded=0,offset=0,left=length;
byte[]bs=newbyte[tmpLength];
while(left>0)
{
try
{
readed=dis.read(bs,0,Math.min(tmpLength,left));
if(readed==-1)
break;
System.arraycopy(bs,0,ret,offset,readed);
}
finally
{
offset+=readed;
left-=readed;
}
}
returnret;
}
}

2.android端
我们主要请求一个数据使一哈。
Activiy中的主要代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/**
*测试一哈
*@paramv
*/
publicvoidtoTest(Viewv){
StringresMsg="写代码真累";
reqCleEdt.setText(resMsg);
try{
byte[]reqData=resMsg.getBytes();
//加密
byte[]encrypt=AESUtil.encrypt(reqData);
reqCipEdt.setText(newString(encrypt));
//压缩
finalbyte[]compress=GZipUtils.compress(encrypt);
newThread(){
publicvoidrun(){
try{
byte[]respData=newTcpUtil().requstData(compress);
//解压缩
finalbyte[]uncompress=GZipUtils.decompress(respData);
//解密
finalbyte[]decrypt=AESUtil.decrypt(uncompress);
runOnUiThread(newRunnable(){
publicvoidrun(){
respCleEdt.setText(newString(decrypt));
respCipEdt.setText(newString(uncompress));
}
});
}catch(InvalidCipherTextExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}catch(Exceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
};
}.start();
}catch(InvalidCipherTextExceptione){
e.printStackTrace();
}catch(Exceptione){
e.printStackTrace();
}
}

上面用到的获取响应数据的方法: byte []respData= new TcpUtil().requstData(compress);我进行了封装,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/**
*@authorqiwenming
*@time2015年5月30日下午4:16:45
*@说明Tcp请求的工具类简单的实现一哈
*/
public class TcpUtil{
private OutputStreamoutputStream;
private InputStreaminputStream;
private Socketsocket;
/**
*请求数据
*@return
*/
public byte []requstData( byte []data) throws Exception{
try {
if (socket== null ){
socket= new Socket( "192.168.1.106" , 10000 );
}
outputStream=socket.getOutputStream();
DataOutputStreamdos= new DataOutputStream(outputStream);
dos.writeInt(data.length);
dos.write(data); //把数据的长度写过去
dos.flush();
socket.shutdownOutput(); //数据发完
byte []recData=responseData();
return recData;
} finally {
// disconnect();
}
}
/**
*响应的数据
*@throwsIOException
*/
public byte []responseData() throws IOException{
inputStream=socket.getInputStream();
DataInputStreamdis= new DataInputStream(inputStream);
//数据的长度
int length=dis.readInt();
int tmpLength= 1024 ; //每次读取最大缓冲区大小
byte []ret= new byte [length]; //读取到流
int readed= 0 ,offset= 0 ,left=length;
byte []bs= new byte [tmpLength];
while (left> 0 )
{
try
{
readed=dis.read(bs, 0 ,Math.min(tmpLength,left));
if (readed==- 1 )
break ;
System.arraycopy(bs, 0 ,ret,offset,readed);
}
finally
{
offset+=readed;
left-=readed;
}
}
return ret;
}
/**
*关闭资源
*@throwsIOException
*/
public void disconnect() throws IOException
{
if (outputStream!= null )
{
outputStream.close();
}
if (inputStream!= null )
{
inputStream.close();
}
if (socket!= null &&!socket.isClosed())
{
socket.shutdownInput();
socket.shutdownOutput();
socket.close();
}
}
}
五、运行结果
如果你在使用的使用GZIP压缩错误的话,使用第三方的包(commons-compress),就ok了。


源码下载





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值