实验内容:
1.运行教材上TCP代码,结对进行,一人服务器,一人客户端;
2.利用加解密代码包,编译运行代码,一人加密,一人解密;
3.集成代码,一人加密后通过TCP发送;
注:加密使用AES或者DES/AES或者DES加密密钥key并发送,使用服务器的公钥加密/公钥算法使用RSA或DH/检验发送信息的完整性使用MD5或者SHA3;
4.用Git进行版本控制。
5.完成Blog
代码:
import java.net.*;
import java.io.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
public class MyServer {
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
ServerSocket sc = null;
ServerSocket sc1 = null;
Socket socket=null;
Socket socket1=null;
try {
sc= new ServerSocket(4431);//创建服务器套接字
sc1= new ServerSocket(4430);//创建服务器套接字
System.out.println("端口号:" + sc.getLocalPort());
System.out.println("服务器1已经启动...");
System.out.println("端口号:" + sc1.getLocalPort());
System.out.println("服务器2已经启动...");
socket = sc.accept(); //等待客户端连接
System.out.println("已经建立连接");
socket1 = sc1.accept(); //等待客户端连接
System.out.println("已经建立1连接");
//获得网络输入流对象的引用
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedReader in1 = new BufferedReader(new InputStreamReader(socket1.getInputStream()));
////获得网络输出流对象的引用
System.out.print("已接收\n");
PrintWriter out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
String aline=in.readLine();//读取客户端传送来的数据
String aline1=in1.readLine();
System.out.print("写入文件中...\n");
byte [] bytes = aline.getBytes("GB2312");
byte [] bytes1 = aline1.getBytes("GB2312");
aline = new String(bytes, "GB2312");
aline1 = new String(bytes1, "GB2312");
FileOutputStream s=new FileOutputStream("key1.dat");
s.write(bytes);
FileOutputStream s1=new FileOutputStream("SEnc.dat");
s1.write(bytes1);
System.out.print("已写入文件\n");
//生成解密密钥
FileInputStream f=new FileInputStream("key1.dat");
ObjectInputStream b=new ObjectInputStream(f);
Key k=(Key)b.readObject( );
byte[ ] kb=k.getEncoded( );
FileOutputStream f2=new FileOutputStream("keykb1.dat");
f2.write(kb);
System.out.print("生成解密密钥\n");
// 打印密钥编码中的内容
for(int i=0;i<kb.length;i++){
// System.out.print(kb[i]+",");
}
//解密
FileInputStream a=new FileInputStream("SEnc.dat");
int num=a.available();
byte[ ] ctext=new byte[num];
a.read(ctext);
FileInputStream f1=new FileInputStream("keykb1.dat");
int num2=f1.available();
byte[ ] keykb=new byte[num2];
f1.read(keykb);
SecretKeySpec e=new SecretKeySpec(keykb,"DESede");
Cipher cp=Cipher.getInstance("DESede");
cp.init(Cipher.DECRYPT_MODE, k);
byte []ptext=cp.doFinal(ctext);
String p=new String(ptext,"GB2312");
System.out.print("解密中...\n");
System.out.println(p);
//返回
System.out.println("从客户端接收到信息为:"+p); //通过网络输出流返回结果给客户端
out.println(p);
out.close();
in.close();
sc.close();
} catch (Exception e) {
System.out.println(e);
}
}
}
运行结果:
遇到的问题:
1、将程序包中程序整合时经常容易出现重定义和变量名占用的问题,此时只需要注销掉重复定义的部分或者更改变量名即可,但要注意后来引用部分也需要更改变量名。
2、同时将加密密钥和密文文件打包发送时服务器无法区分两个数据流。重新定义一个新端口4430,将两个文件通过两个不同的端口4431和4430分别发送。
3、文件发送后string型数据无法转换为FileOutputStream型数据,无法写入文件。通过查询资料,按照 GB2312 得到字节(得到多字节字符串)
byte [] bytes = string.getBytes("GB2312");
从字节按照 GB2312 得到 UNICODE 字符串
string = new String(bytes, "GB2312");
用 Stream 类写入已经按照指定编码转化好的字节串
OutputStream os = new FileOutputStream("1.txt");
os.write(bytes);
os.close();
实验体会:
本次实验是我和搭档结对完成的,虽然大部分代码是现成的,但是整合起来却十分的麻烦,要把DES加密、RSA加密的代码整合在一个程序中并且要编译成功是一件十分困难的事情,一不小心就会漏洞百出,而在网络连接,传送,反馈上也有很多很难的地方,遇到有问题的地方往往需要上网翻阅很多资料才能找到适合的解决方案,在对代码的不断调试、改进、调试、改进后,最终编译成功。