(1)结对实现中缀表达式转后缀表达式的功能 MyBC.java
结对实现从上面功能中获取的表达式中实现后缀表达式求值的功能,调用MyDC.java
上传测试代码运行结果截图和码云连接html
(2)结对编程:1人负责客户端,一人负责服务器
注意责任归宿,要会经过测试证实本身没有问题
基于Java Socket实现客户端/服务器功能,传输方式用TCP
客户端让用户输入中缀表达式,而后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式经过网络发送给服务器
服务器接收到后缀表达式,调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
客户端显示服务器发送过来的结果
上传测试结果截图和码云连接java
(3)加密结对编程:1人负责客户端,一人负责服务器
注意责任归宿,要会经过测试证实本身没有问题
基于Java Socket实现客户端/服务器功能,传输方式用TCP
客户端让用户输入中缀表达式,而后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密后经过网络把密文发送给服务器
服务器接收到后缀表达式表达式后,进行解密(和客户端协商密钥,能够用数组保存),而后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
客户端显示服务器发送过来的结果
上传测试结果截图和码云连接git
(4)密钥分发结对编程:1人负责客户端,一人负责服务器
注意责任归宿,要会经过测试证实本身没有问题
基于Java Socket实现客户端/服务器功能,传输方式用TCP
客户端让用户输入中缀表达式,而后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密经过网络把密文发送给服务器
客户端和服务器用DH算法进行3DES或AES算法的密钥交换
服务器接收到后缀表达式表达式后,进行解密,而后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
客户端显示服务器发送过来的结果
上传测试结果截图和码云连接算法
(5)完整性校验结对编程:1人负责客户端,一人负责服务器
注意责任归宿,要会经过测试证实本身没有问题
基于Java Socket实现客户端/服务器功能,传输方式用TCP
客户端让用户输入中缀表达式,而后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密经过网络把密文和明文的MD5値发送给服务器
客户端和服务器用DH算法进行3DES或AES算法的密钥交换
服务器接收到后缀表达式表达式后,进行解密,解密后计算明文的MD5值,和客户端传来的MD5进行比较,一致则调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端
客户端显示服务器发送过来的结果
上传测试结果截图和码云连接编程
这里是要求咱们:①结对实现中缀表达式转后缀表达式的功能 MyBC.java,②结对实现从上面功能中获取的表达式中实现后缀表达式求值的功能。
由于咱们前面已经作完告终对编程任务——四则运算,这里作起来就比较简单,将以前的两个类调用过来,编写一个驱动类便可完成实验一,这里是驱动类的代码:数组
public class MyDC { public static void main(String[] args) { Questions questions = new Questions(); String question = String.valueOf(questions.getQuestion()); System.out.println("问题:"+question); suffix suffix = new suffix(); String answer = suffix.getAnswer(question); System.out.println("后缀:"+answer); Calculations calculation = new Calculations(); String result = calculation.getresult(answer); System.out.println("求值:"+result); } }
具体的每一个类的代码这里再也不展现,可参见码云连接:实验一
运行的结果截图如图:
服务器
要求是:①结对编程:一人负责客户端,另外一人负责服务器;②注意责任归宿,要会经过测试证实本身没有问题;③基于Java Socket实现客户端/服务器功能,传输方式用TCP;④客户端让用户输入中缀表达式,而后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式经过网络发送给服务器;⑤服务器接收到后缀表达式,调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端;⑥客户端显示服务器发送过来的结果。
这里是首先须要了解Socket通讯是什么:网络
网络上的两个程序经过一个双向的通信链接实现数据的交换,这个双向链路的一端称为一个Socket。Socket一般用来实现客户方和服务方的链接。Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号惟一肯定。可是,Socket所支持的协议种类也不光TCP/IP一种,所以二者之间是没有必然联系的。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。数据结构
再来了解如下Socket通讯的过程是怎样的:
Server 端Listen(监听)某个端口是否有链接请求,Client端向Server端发出Connect(链接)请求,Server端向Client端发回 Accept(接受)消息。一个链接就创建起来了。Server端和Client端均可以经过Send,Write等方法与对方通讯。
对于一个功能齐全的Socket,都要包含如下基本结构,其工做过程包含如下四个基本的步骤:
-(1) 建立Socket;
-(2) 打开链接到Socket的输入/出流;
-(3) 按照必定的协议对Socket进行读/写操做;
-(4) 关闭Socket.(在实际应用中,并未使用到显示的close,虽然不少文章都推荐如此,不过在个人程序中,可能由于程序自己比较简单,要求不高,因此并未形成什么影响。)多线程
简单了解之后,咱们根据老师所给的初始代码进行修改,这里是我充当的角色为服务器,即需接收客户端传来的后缀表达式,并进行计算求值,再将结果返回给客户端,这里的代码见下:
package exp5; import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.StringTokenizer; /** * Created by besti on 2018/6/9. */ public class SocketServer { public static void main(String[] args) throws IOException { //1.创建一个服务器Socket(ServerSocket)绑定指定端口 ServerSocket serverSocket=new ServerSocket(8800); //2.使用accept()方法阻止等待监听,得到新链接 Socket socket=serverSocket.accept(); //3.得到输入流 InputStream inputStream=socket.getInputStream(); BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream,"UTF-8")); //得到输出流 OutputStream outputStream=socket.getOutputStream(); PrintWriter printWriter=new PrintWriter(outputStream); //4.读取用户输入信息 String info=null; info = bufferedReader.readLine(); System.out.println("我是20172302侯泽洋,用户20172308周亚杰发送信息为:" + info); Calculations calculations = new Calculations(); String reply = calculations.getresult(info); //给客户一个响应 printWriter.write(reply); printWriter.flush(); //5.关闭资源 printWriter.close(); outputStream.close(); bufferedReader.close(); inputStream.close(); socket.close(); serverSocket.close(); } }
客户端的代码是归伙伴负责,这里将码云连接给出:
实验二
运行结果截图:
题目:①客户端让用户输入中缀表达式,而后把中缀表达式调用MyBC.java的功能转化为后缀表达式,把后缀表达式用3DES或AES算法加密后经过网络把密文发送给服务器;②服务器接收到后缀表达式表达式后,进行解密(和客户端协商密钥,能够用数组保存),而后调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端。
这里是要求的咱们在实验二的基础之上,把传输内容进行加密,再也不进行明文传输,又须要用到咱们所作的实验三的密码学算法的内容,又把以前的内容复习了一遍,关于DES加密的过程这里再也不进行阐述,可参见实验三博客内容。
这里须要传输的密文是一个byte型的数组,咱们采用字节流直接对它进行传输和接收,我负责的服务器端具体代码见下:
package exp5; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.SecretKeySpec; import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.StringTokenizer; import static java.awt.SystemColor.info; /** * Created by besti on 2018/6/9. */ public class SocketServer { public static void main(String[] args) throws IOException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { //1.创建一个服务器Socket(ServerSocket)绑定指定端口 ServerSocket serverSocket=new ServerSocket(8800); //2.使用accept()方法阻止等待监听,得到新链接 Socket socket=serverSocket.accept(); //3.得到输入流 InputStream inputStream=socket.getInputStream(); BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream,"UTF-8")); //得到输出流 OutputStream outputStream=socket.getOutputStream(); PrintWriter printWriter=new PrintWriter(outputStream); //4.读取用户输入信息 byte[] ctext = inputStream.readAllBytes(); for(int i=0;i<ctext.length;i++){ System.out.print(ctext[i]+","); } System.out.println(); // 获取密钥 FileInputStream f3=new FileInputStream("keykb1.dat"); int num2=f3.available(); byte[] keykb=new byte[num2]; f3.read(keykb); SecretKeySpec k=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,"UTF8"); System.out.println(p); Calculations calculations = new Calculations(); String reply = calculations.getresult(p); //给客户一个响应 printWriter.write(reply); printWriter.flush(); //5.关闭资源 printWriter.close(); outputStream.close(); bufferedReader.close(); inputStream.close(); socket.close(); serverSocket.close(); } }
伙伴负责的是客户端的部分,码云连接为:实验三
运行结果截图:
实验题目:在实验三基础上进行客户端和服务器用DH算法进行3DES或AES算法的密钥交换,这里咱们选择的是DH算法进行AES算法的密钥交换,
建立DH算法的公钥和私钥:
package experiment4; import javax.crypto.spec.DHParameterSpec; import java.io.FileOutputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; public class Key_DH { //三个静态变量的定义从 // C:\j2sdk-1_4_0-doc\docs\guide\security\jce\JCERefGuide.html // 拷贝而来 // The 1024 bit Diffie-Hellman modulus values used by SKIP private static final byte skip1024ModulusBytes[] = { (byte)0xF4, (byte)0x88, (byte)0xFD, (byte)0x58, (byte)0x4E, (byte)0x49, (byte)0xDB, (byte)0xCD, (byte)0x20, (byte)0xB4, (byte)0x9D, (byte)0xE4, (byte)0x91, (byte)0x07, (byte)0x36, (byte)0x6B, (byte)0x33, (byte)0x6C, (byte)0x38, (byte)0x0D, (byte)0x45, (byte)0x1D, (byte)0x0F, (byte)0x7C, (byte)0x88, (byte)0xB3, (byte)0x1C, (byte)0x7C, (byte)0x5B, (byte)0x2D, (byte)0x8E, (byte)0xF6, (byte)0xF3, (byte)0xC9, (byte)0x23, (byte)0xC0, (byte)0x43, (byte)0xF0, (byte)0xA5, (byte)0x5B, (byte)0x18, (byte)0x8D, (byte)0x8E, (byte)0xBB, (byte)0x55, (byte)0x8C, (byte)0xB8, (byte)0x5D, (byte)0x38, (byte)0xD3, (byte)0x34, (byte)0xFD, (byte)0x7C, (byte)0x17, (byte)0x57, (byte)0x43, (byte)0xA3, (byte)0x1D, (byte)0x18, (byte)0x6C, (byte)0xDE, (byte)0x33, (byte)0x21, (byte)0x2C, (byte)0xB5, (byte)0x2A, (byte)0xFF, (byte)0x3C, (byte)0xE1, (byte)0xB1, (byte)0x29, (byte)0x40, (byte)0x18, (byte)0x11, (byte)0x8D, (byte)0x7C, (byte)0x84, (byte)0xA7, (byte)0x0A, (byte)0x72, (byte)0xD6, (byte)0x86, (byte)0xC4, (byte)0x03, (byte)0x19, (byte)0xC8, (byte)0x07, (byte)0x29, (byte)0x7A, (byte)0xCA, (byte)0x95, (byte)0x0C, (byte)0xD9, (byte)0x96, (byte)0x9F, (byte)0xAB, (byte)0xD0, (byte)0x0A, (byte)0x50, (byte)0x9B, (byte)0x02, (byte)0x46, (byte)0xD3, (byte)0x08, (byte)0x3D, (byte)0x66, (byte)0xA4, (byte)0x5D, (byte)0x41, (byte)0x9F, (byte)0x9C, (byte)0x7C, (byte)0xBD, (byte)0x89, (byte)0x4B, (byte)0x22, (byte)0x19, (byte)0x26, (byte)0xBA, (byte)0xAB, (byte)0xA2, (byte)0x5E, (byte)0xC3, (byte)0x55, (byte)0xE9, (byte)0x2F, (byte)0x78, (byte)0xC7 }; // The SKIP 1024 bit modulus private static final BigInteger skip1024Modulus = new BigInteger(1, skip1024ModulusBytes); // The base used with the SKIP 1024 bit modulus private static final BigInteger skip1024Base = BigInteger.valueOf(2); public static void main(String args[ ]) throws Exception{ DHParameterSpec DHP= new DHParameterSpec(skip1024Modulus,skip1024Base); KeyPairGenerator kpg= KeyPairGenerator.getInstance("DH"); kpg.initialize(DHP); KeyPair kp=kpg.genKeyPair(); PublicKey pbk=kp.getPublic(); PrivateKey prk=kp.getPrivate(); // 保存公钥 FileOutputStream f1=new FileOutputStream(args[0]); ObjectOutputStream b1=new ObjectOutputStream(f1); b1.writeObject(pbk); // 保存私钥 FileOutputStream f2=new FileOutputStream(args[1]); ObjectOutputStream b2=new ObjectOutputStream(f2); b2.writeObject(prk); } }
接下来咱们交换了各自产生的公钥文件,而后将由公钥私钥配对产生密钥的过程放入到咱们的服务器和客户端的运行过程当中,服务器端完成的代码见下:
package exp5; import javax.crypto.*; import javax.crypto.spec.SecretKeySpec; import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.util.StringTokenizer; import static java.awt.SystemColor.info; /** * Created by besti on 2018/6/9. */ public class SocketServer { public static void main(String[] args) throws IOException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, ClassNotFoundException { //1.创建一个服务器Socket(ServerSocket)绑定指定端口 ServerSocket serverSocket=new ServerSocket(9901); //2.使用accept()方法阻止等待监听,得到新链接 Socket socket=serverSocket.accept(); //3.得到输入流 InputStream inputStream=socket.getInputStream(); BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream,"UTF-8")); //得到输出流 OutputStream outputStream=socket.getOutputStream(); PrintWriter printWriter=new PrintWriter(outputStream); //4.读取用户输入信息 byte[] ctext = inputStream.readAllBytes(); for(int i=0;i<ctext.length;i++){ System.out.print(ctext[i]+","); } System.out.println(); // 读取对方的DH公钥 FileInputStream f1=new FileInputStream("Apub.dat"); ObjectInputStream b1=new ObjectInputStream(f1); PublicKey pbk=(PublicKey)b1.readObject( ); //读取本身的DH私钥 FileInputStream f2=new FileInputStream("Bpri.dat"); ObjectInputStream b2=new ObjectInputStream(f2); PrivateKey prk=(PrivateKey)b2.readObject( ); // 执行密钥协定 KeyAgreement ka=KeyAgreement.getInstance("DH"); ka.init(prk); ka.doPhase(pbk,true); //生成共享信息 byte[ ] sb=ka.generateSecret(); for(int i=0;i<sb.length;i++){ System.out.print(sb[i]+","); } SecretKeySpec k=new SecretKeySpec(sb,0,24,"AES"); // 解密 Cipher cp=Cipher.getInstance("AES"); cp.init(Cipher.DECRYPT_MODE, k); byte[] ptext = cp.doFinal(ctext); // 显示明文 String p=new String(ptext,"UTF8"); System.out.println(p); Calculations calculations = new Calculations(); String reply = calculations.getresult(p); //给客户一个响应 printWriter.write(reply); printWriter.flush(); //5.关闭资源 printWriter.close(); outputStream.close(); bufferedReader.close(); inputStream.close(); socket.close(); serverSocket.close(); } }
客户端由伙伴完成,码云连接:实验四
运行结果截图:
在实验四基础上,服务器接收到后缀表达式表达式后,进行解密,解密后计算明文的MD5值,和客户端传来的MD5进行比较,一致则调用MyDC.java的功能计算后缀表达式的值,把结果发送给客户端。
仍然须要复习MD5值的加密过程,如下为MD5加密的代码过程:
String x = info; MessageDigest m2 = MessageDigest.getInstance("MD5"); m2.update(x.getBytes()); byte a[] = m2.digest(); String result = ""; for (int i = 0; i < a.length; i++) { result += Integer.toHexString((0x000000ff & a[i]) | 0xffffff00).substring(6); } System.out.println(result); out.println(result);//经过网络将明文的Hash函数值传送到服务器 str = in.readLine();// 从网络输入流读取结果 System.out.println("从服务器接收到的结果为:" + str); // 输出服务器返回的结果
而后咱们将MD5值以String类型数据进行传输,我进行接收,我负责的服务器端的代码:
package exp5; import javax.crypto.*; import javax.crypto.spec.SecretKeySpec; import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.security.*; import java.util.StringTokenizer; import static java.awt.Color.white; import static java.awt.SystemColor.info; /** * Created by besti on 2018/6/9. */ public class SocketServer { public static void main(String[] args) throws IOException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, ClassNotFoundException { //1.创建一个服务器Socket(ServerSocket)绑定指定端口 ServerSocket serverSocket=new ServerSocket(9901); //2.使用accept()方法阻止等待监听,得到新链接 Socket socket=serverSocket.accept(); //3.得到输入流 InputStream inputStream=socket.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream,"UTF-8"); BufferedReader bufferedReader=new BufferedReader(inputStreamReader); //得到输出流 OutputStream outputStream=socket.getOutputStream(); PrintWriter printWriter=new PrintWriter(outputStream); //4.读取用户输入信息 String[] array = new String[2]; String info= null; String in =null; int i = 0; while(!((info = bufferedReader.readLine()) ==null)) { array[i] = info; i++; } String ra = array[0]; StringTokenizer stringTokenizer = new StringTokenizer(ra); System.out.println("客户端传来的密文:"+ra); byte[] ctext = {-64,-111,-17,100,71,-119,-4,57,-25,-110,-24,-58,-68,48,-124,-126}; System.out.println(); String ai = array[1]; System.out.println("客户端传来的MD5值:"+ai); System.out.println(); // 读取对方的DH公钥 FileInputStream f1=new FileInputStream("Apub.dat"); ObjectInputStream b1=new ObjectInputStream(f1); PublicKey pbk=(PublicKey)b1.readObject( ); //读取本身的DH私钥 FileInputStream f2=new FileInputStream("Bpri.dat"); ObjectInputStream b2=new ObjectInputStream(f2); PrivateKey prk=(PrivateKey)b2.readObject( ); // 执行密钥协定 KeyAgreement ka=KeyAgreement.getInstance("DH"); ka.init(prk); ka.doPhase(pbk,true); //生成共享信息 byte[ ] sb=ka.generateSecret(); System.out.println("公钥、私钥配对产生密钥为:"); for(int x=0;x<sb.length;x++){ System.out.print(sb[x]+","); } SecretKeySpec k=new SecretKeySpec(sb,0,24,"AES"); // 解密 Cipher cp=Cipher.getInstance("AES"); cp.init(Cipher.DECRYPT_MODE, k); byte[] ptext = cp.doFinal(ctext); // 显示明文 String p=new String(ptext,"UTF8"); System.out.println(); System.out.println(p); MessageDigest m=MessageDigest.getInstance("MD5"); m.update(p.getBytes("UTF8")); byte s[ ]=m.digest( ); String result=""; for (int u=0; u<s.length; u++){ result+=Integer.toHexString((0x000000ff & s[u]) | 0xffffff00).substring(6); } System.out.println("解密后获得的后缀表达式的MD5值"+result); if (result.equals(ai)){ System.out.println("明文的MD5和客户端传来的MD5值相等,则计算并求值发送给客户端"); Calculations calculations = new Calculations(); String reply = calculations.getresult(p); //给客户一个响应 printWriter.write(reply); printWriter.flush(); } //5.关闭资源 printWriter.close(); outputStream.close(); bufferedReader.close(); inputStream.close(); socket.close(); serverSocket.close(); } }
伙伴的代码见下:
package experiment4; import javax.crypto.*; import javax.crypto.spec.SecretKeySpec; import java.io.*; import java.net.Socket; import java.security.*; import java.util.Scanner; /** * Created by besti on 2018/6/9. */ public class SocketClient { public static void main(String[] args) throws IOException, InvalidKeyException, ClassNotFoundException, NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException { //1.创建客户端Socket链接,指定服务器位置和端口 // Socket socket = new Socket("localhost",8080); Socket socket = new Socket("172.16.43.121",9901); //2.获得socket读写流 OutputStream outputStream = socket.getOutputStream(); // PrintWriter printWriter = new PrintWriter(outputStream); OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream); //输入流 InputStream inputStream = socket.getInputStream(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream,"UTF-8")); //3.利用流按照必定的操做,对socket进行读写操做 System.out.println("请输入一个问题:");//输入中缀 Scanner scan =new Scanner(System.in); String info2 =scan.nextLine(); suffix suffix = new suffix(); String info1 = suffix.getAnswer(info2);//转后缀 System.out.println("后缀:"+info1); System.out.println(); System.out.println("密钥:"); // 读取对方的DH公钥 FileInputStream f1=new FileInputStream("Bpub.dat"); ObjectInputStream b1=new ObjectInputStream(f1); PublicKey pbk=(PublicKey)b1.readObject( ); //读取本身的DH私钥 FileInputStream f2=new FileInputStream("Apri.dat"); ObjectInputStream b2=new ObjectInputStream(f2); PrivateKey prk=(PrivateKey)b2.readObject( ); // 执行密钥协定 KeyAgreement ka= KeyAgreement.getInstance("DH"); ka.init(prk); ka.doPhase(pbk,true); //生成共享信息 byte[ ] sb=ka.generateSecret(); for(int i=0;i<sb.length;i++){ System.out.print(sb[i]+","); } SecretKeySpec k=new SecretKeySpec(sb,0,24,"AES");//生成密钥 Cipher cp=Cipher.getInstance("AES"); cp.init(Cipher.ENCRYPT_MODE, k); byte ptext[]=info1.getBytes("UTF8"); for(int i=0;i<ptext.length;i++){ System.out.print(ptext[i]+","); } System.out.println(""); byte ctext[]=cp.doFinal(ptext); for(int i=0;i<ctext.length;i++){ System.out.print(ctext[i] +","); } System.out.println(); FileOutputStream f3=new FileOutputStream("SEnc.dat");//密文加密 f3.write(ctext); String x=info1; MessageDigest m=MessageDigest.getInstance("MD5"); m.update(x.getBytes("UTF8")); byte s[ ]=m.digest( ); String result=""; for (int i=0; i<s.length; i++){ result+=Integer.toHexString((0x000000ff & s[i]) | 0xffffff00).substring(6); } System.out.println("明文的MD5值:"+result); String ai =""; for (int i=0;i<ctext.length;i++) { ai+=ctext[i]+" "; } System.out.println("密文:"+ai); outputStreamWriter.write(ai+"\n"+result);//传输密文 outputStreamWriter.flush(); socket.shutdownOutput(); //接收服务器的响应 String reply = null; reply = bufferedReader.readLine(); System.out.println("结果:"+reply); //4.关闭资源 bufferedReader.close(); inputStream.close(); //printWriter.close(); outputStream.close(); socket.close(); } }
咱们完成的实验的码云连接:实验五
运行的结果截图:
问题1:进行第三个实验时,咱们遇到了一些问题,即将字节型数组的密文转换成String类型时,传输过来时,老是会出现乱码,结果致使没有办法解密。
问题1解决方案:这里显示的密文是不合法的,咱们在这里卡了好久,最后采用的是再也不进行转换成String类型的转换,咱们直接将密文的byte数组使用字节流传输,接收时使用一个byte的数组进行接收,这里就没有问题了,具体代码是客户端是outputStream.write(ctext);outputStream.flush();
,服务器是byte[] ctext = inputStream.readAllBytes();
,最后就是这样,将密文传输过来,并完成后续步骤。
问题2:实验四时,咱们一开始采用的用DH算法对DES加密进行产生密文,可是在加密时,这里的始终是DH算法产生的密钥格式存在问题,问题具体见图:
问题2解决方案:最后咱们采用了伙伴提出的使用AES进行加密,可是这里也遇到了些问题,依旧加密过程存在问题,询问了余坤澎他们小组,对一处进行修改后完成,修改的内容为由SecretKeySpec k=new SecretKeySpec(sb,"AES");
改成SecretKeySpec k=new SecretKeySpec(sb,0,24,"AES");
,经过查询API文档,咱们对这里有了必定了解。
问题3:实验5中咱们将byte数组的密文直接转换成了String类型,传输过去就会出现以下图这样的一串应密文的数字格式:
问题3解决方案:把两条数据都写在一个输出语句中。但这样就有两种作法:一是把字节型的密文转换成字符串类型;二是把字符串类型的MD5值写进存放密文的字节数组。咱们选择了前者,可是致使的问题就是如问题5所叙述的那样,客户端输出的结果是正确无误的,可是传到服务器端以后,显示出来的就是如上图所示,这个咱们实在是没有一点办法,彻底也不懂,最后咱们的解决方案是将byte数组中每一个元素取出,写入一个String字符串中,而后接收这个字符串后将逐个拿出放入byte数组中,从而实现了密文的传递。