在本次实验中我主要使用了书本第13章Java网络编程以及Java密码学的内容,基于TCP的信息传输使用socket进行实现,加密、解密、生成共享密钥以及进行摘要验证使用了Java中的JCA以及JCE。html
任务要求:算法
虽然该功能是后续步骤的基础,但在之前的结对项目中已经实现过了,在这里我就再也不多作介绍了,详情请见博客结对编程项目-四则运算阶段性总结
运行结果如图:
编程
任务要求:数组
步骤:
一、建立数据输入以及输出流对象in和out用于创建链接后的数据传输。
二、客户端建立套接字对象mysocket,并用构造方法Socket(String host,int port)给mysocket建立实体,而后让mysocket调用getInputStream以及getoutputStream方法与服务器端创建链接。服务器端的步骤与客户端相似,但在建立套接字时服务器端先建立一个ServerSocket对象,并用该对象调用accept方法来建立Socket类的实例。
三、客户端与服务器端分别用对象out调用writeUTF方法来发送数据,对象in调用readUTF来接收数据。客户端在输入中缀表达式后转化为后缀表达式并经过out对象发送给服务器,服务器用in对象接收客户端发送过来的后缀表达式进行计算,并将计算结果使用out对象发送给客户端,客户端使用in对象接收客户端发来的数据并输出。
运行结果以下:
安全
任务要求:服务器
该任务是在任务二的基础上进行功能拓展,因而本任务中的网络信息收发部分我就再也不介绍,我主要对加密及解密过程进行描述,而生成密钥以及加密解密我都放在了Skey_kb
类中,并经过方法来实现功能的调用。
加解密步骤:网络
一、生成密钥并发
kg=KeyGenerator.getInstance("DESede");
kg.init(168);
k=kg.generateKey( );
FileOutputStream f=new FileOutputStream("key1.dat");ObjectOutputStream b=new ObjectOutputStream(f);b.writeObject(k);
二、改变密钥保存方式
在解密时须要使用字节数组形式的密钥,所以须要将密钥以另外一种方式保存在文件中。less
三、加密socket
FileInputStream f=new FileInputStream("key1.dat");ObjectInputStream b=new ObjectInputStream(f);Key k=(Key)b.readObject( );
cp=Cipher.getInstance("DESede");
cp.init(Cipher.ENCRYPT_MODE, k);
String s="Hello World!";` byte ptext[]=s.getBytes("UTF8");
byte ctext[]=cp.doFinal(ptext);
FileOutputStream f2=new FileOutputStream("SEnc.dat"); f2.write(ctext);
四、解密
FileInputStream f=new FileInputStream("SEnc.dat"); int num=f.available(); byte[ ] ctext=new byte[num]; f.read(ctext);
须要注意的是,加密和解密的方法须要分别传入明文以及密文的字符串,并将对应的密文以及明文做为方法的输出。在加密时须要将密文二进制字节数组转化为十六进制后再转化为字符串做为发送数据,在解密时须要将密文转化为二进制后再进行解密。若是不进行数据转化的话在进行密文传输时系统会报错。
运行结果以下:
服务器端:
客户端:
任务要求:
该过程是在任务三的基础上进行的,我在这里只介绍DH算法相关的内容。因为生成公共密钥前须要两端交换公钥,而两端在两个不一样的文件夹中,因而我我在调用程序生成两端各自的两个密钥后,使用套接字在客户端与服务器之间进行了沟通,客户端首先会给服务器发送已生成两个密钥钥的信息,服务器在接收到该消息时也已经生成了两个密钥,在这时须要手动将二者的pub.dat文件进行交换,并在交换完成后在服务器端输入准备好了的信息,并发送给客户端,这样一来就能够正常进行加密及解密密钥的生成了。须要注意的是因为咱们使用的3DES是对外公布的限制密钥长度的版本,而DH算法生成的共享密钥有128位,因此须要在生成加密密钥后取得共享密钥的前几位,不然系统会显示密钥长度不合法。
运行结果以下:
任务要求:
在这部分中我增长了一次out以及in的调用用于两端传递摘要,MD5建立摘要的过程以下所示:
一、生成MessageDigest对象MessageDigest
二、传入须要计算的字符串m.update(x.getBytes("UTF8" ));
三、 计算消息摘要byte s[ ]=m.digest( );
四、将计算结果s转换为字符串
运行结果如图:
服务器:
客户端:
本次实验是网络编程以及Java密码学的一个综合,在实验过程当中遇到的问题使我印象深入,SOLID原则十分重要,它不只能减小代码的数量,更使得程序更加易读,更易于修改,且不容易出错。基于TCP的数据传输也不是为所欲为的,其对传输内容的格式也有要求,若是胡乱对传输内容进行格式转换就极可能出错。而咱们使用的JCE以及JCA都是限制功能的版本,在加密时只能使用很短的密钥,从这也看出发达国家对技术的严格管制。