Experimental Report on Network Programming and Security of Experiment 5, No. 20175313

Catalog

I. Experimental Contents

Task 1: Implement suffix expression to suffix expression and evaluate suffix expression

  1. Refer to http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA
  2. Knot pairing implements the function of infix expression to suffix expression MyBC.java
  3. Knot pair implements the function of evaluating suffix expressions from the expressions obtained from the above functions, and calls MyDC.java
  4. Upload screenshots of test code run results and code cloud links

Task 2: Implement Task 1 through Client and Server

  1. Pay attention to the responsibility and prove that you have no problem by testing.
  2. Implementing client/server function based on Java Socket and using TCP as transmission mode
  3. The client lets the user enter the suffix expression, and then converts the function of the suffix expression calling MyBC.java into the suffix expression, and sends the suffix expression to the server through the network.
  4. The server receives the suffix expression, calls MyDC.java's function to calculate the value of the suffix expression, and sends the result to the client.
  5. The client displays the results sent by the server
  6. Upload screenshots of test results and code cloud links

Task 3: On the basis of Task 2, encrypt the suffix expression generated by the client and pass it to the server

  1. Pay attention to the responsibility and prove that you have no problem by testing.
  2. Implementing client/server function based on Java Socket and using TCP as transmission mode
  3. The client lets the user enter the infix expression, and then converts the function of the infix expression calling MyBC.java into the suffix expression. The suffix expression is encrypted with 3DES or AES algorithm, and the ciphertext is sent to the server through the network.
  4. After receiving the suffix expression, the server decrypts it (negotiates the key with the client, which can be saved in an array), and then calls MyDC.java's function to calculate the value of the suffix expression, and sends the result to the client.
  5. The client displays the results sent by the server
  6. Upload screenshots of test results and code cloud links

Task 4: On the basis of Task 3, the key used for encryption and decryption is exchanged by DH algorithm.

  1. Pay attention to the responsibility and prove that you have no problem by testing.
  2. Implementing client/server function based on Java Socket and using TCP as transmission mode
  3. The client lets the user enter the infix expression, and then converts the function of the infix expression calling MyBC.java into the suffix expression. The suffix expression is encrypted by 3DES or AES algorithm, and the ciphertext is sent to the server through the network.
  4. Key Exchange of 3D ES or AES Algorithms Using DH Algorithms between Client and Server
  5. After receiving the suffix expression, the server decrypts it, then calls MyDC.java's function to calculate the value of the suffix expression and sends the result to the client.
  6. The client displays the results sent by the server
  7. Upload screenshots of test results and code cloud links

Task 5: On the basis of Task 4, the summary value of the suffix expression is passed to the server. The server calculates the MD5 value of the suffix expression after decryption, and compares whether the value is the same as that from the client.

  1. Pay attention to the responsibility and prove that you have no problem by testing.
  2. Implementing client/server function based on Java Socket and using TCP as transmission mode
  3. The client lets the user enter the infix expression, and then converts the function of the infix expression calling MyBC.java into the suffix expression. The suffix expression is encrypted by 3DES or AES algorithm, and the encrypted and plaintext MD5 s are sent to the server through the network.
  4. Key Exchange of 3D ES or AES Algorithms Using DH Algorithms between Client and Server
  5. After receiving the expression of suffix expression, the server decrypts it, calculates the MD5 value of plaintext after decryption, compares it with the MD5 value transmitted from the client, and consistently calls MyDC.java's function to calculate the value of the expression of suffix, and sends the result to the client.
  6. The client displays the results sent by the server
  7. Upload screenshots of test results and code cloud links

II. EXPERIMENTAL STEPS

This experiment has five small steps, each step is based on the previous step of expansion.

3. Key Code Parsing

Task 1: Transform suffixes by suffix expression rules

  • Interfix to suffix

    • If an operand is encountered, it is output directly.
    • If you encounter an operator, put it on the stack, and if you encounter a left parenthesis, put it in the stack.
      Stack.
    • If you encounter right parentheses, pop up stack elements and output pop-up operators until you encounter left parentheses. Note that left parentheses only pop up and do not output.
    • If you encounter any other operators, such as "+", -"*", "", (), pop up elements from the stack until you encounter them.
      Elements of lower priority or stack empty. These elements are popped up before the operators encountered are pushed into the stack.
    • If you read the end of the input, all the elements in the stack pop up in turn.
    while (tokenizer.hasMoreTokens()){
              token=tokenizer.nextToken();
              if (isOperator(token)){
                  if (!OpStack.empty()){
                      if(judgeValue(token)>judgeValue(OpStack.peek()) && !token.equals(")") || token.equals("("))
                          OpStack.push(token);
                      else if (token.equals(")")){
                          //If you encounter a right bracket, the stack element pops up and the pop-up operator is output until you encounter the left bracket.
                          while (!OpStack.peek().equals("("))
                              output=output.concat(OpStack.pop()+" ");//Pop up everything above the left bracket
                          OpStack.pop();//Pop-up left parentheses
                      }
                      else {
                          while (!OpStack.empty() && judgeValue(token)<=judgeValue(OpStack.peek())){
                              //// If you encounter any other operator, pop these elements out of the stack until you encounter a lower priority element or empty stack
                              output=output.concat(OpStack.pop()+" ");
                          }
                          OpStack.push(token);
                      }
                  }
                  else
                      OpStack.push(token);//If the stack is empty, the operator encountered is directly put into the stack. The first one cannot be a right parenthesis.
              }
              else {
                  output=output.concat(token+" ");//Direct output if operands are encountered
              }
          }
          while (!OpStack.empty()){
              //If you read the end of the input sub-point, all the elements in the input sub-point will pop up in turn.
              output=output.concat(OpStack.pop()+" ");
          }
  • Computation using suffix expression rules
  • Rule: traverse every number and symbol of the expression from left to right, enter the stack when it encounters the number, and out of the stack when it encounters the symbol, carry out operations on the two digits at the top of the stack, and put the results into the stack until the final result is obtained.
while (tokenizer.hasMoreTokens()){
    token=tokenizer.nextToken();
        if(isOperator(token)){
        //When an operator is encountered, two operands exit the stack
            op2=stack.pop();
            op1=stack.pop();
            result=calcSingle(op1,op2,token);//Two operands perform correlation operations
                stack.push(new Integer(result));//The result of the operation is stacked
            }
        else {
        //Encounter digital stacking
                stack.push(new Integer(token));
            }
    }
  • Call String getEquation(String s) of MyBC class; method converts infix expression into suffix expression
MyBC myBC = new MyBC();
output = myBC.getEquation(formula);
  • Call the String calculate (String) method of MyDC class to compute the result of the resulting suffix expression
MyDC myDC = new MyDC();
result = myDC.calculate(formula);

Task 2: The client inputs the suffix expression and sends it to the server. The server calculates the suffix expression and sends the result to the client.

  • Use regular expressions to determine whether an input infix expression is legitimate
    String formula = scanner.nextLine();
    String regex = ".*[^0-9|+|\\-|*|÷|(|)|\\s|/].*";
    if(formula.matches(regex)){
        System.out.println("Illegal character input");
        System.exit(1);
    }

Task 3: The suffix expression obtained by the client is encrypted by 3DES or AES, and then the ciphertext is sent to the server. The server decrypts the suffix expression after receiving it, then calculates the value of the suffix expression, and sends the result to the client.

  1. Get the key generator: KeyGenerator kg=KeyGenerator.getInstance("AES");
  2. Initialization key generator: kg.init(128);
  3. Generation key: SecretKey k=kg.generateKey();
  4. Create a cryptograph
    Cipher cp=Cipher.getInstance("DESede");
  5. Initialization cryptograph
    cp.init(Cipher.ENCRYPT_MODE,k);
  6. Execute encryption
    byte []ctext=cp.doFinal(ptext);
  • Note: The ciphertext generated here is a byte [] array, but the parameters to be passed to the server should be String type, if String s = new String(ctext) is used directly; this construction method may result in javax. crypto. Illegal BlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher.
  • Reason: Encrypted byte arrays cannot be forced into strings, in other words: strings and byte arrays are not reciprocal in this case; to avoid this situation, we need to make some revisions, we can consider converting binary data into hexadecimal representation.
  • So here I convert ctext [] binary to hexadecimal and send it to the server. After the server receives it, it can convert hexadecimal to binary. (The same is true for subsequent key transfers)
  • Client-side code:
String out1 = B_H.parseByte2HexStr(ctext);
out.writeUTF(out1);
  • Server side code:
String cformula = in.readUTF();//Read ciphertext
byte cipher[] = H_B.parseHexStr2Byte(cformula);
  • Key transfer process:
    • The SecretKey type key is converted to byte [], which is then transmitted to the server in the same way as ciphertext.
      byte kb[] = k.getEncoded();
    • Convert byte [] to SecretKeySpec and get the key
      SecretKeySpec key = new SecretKeySpec(decryptKey,"AES"; //Get the key

Task 4: Using DH algorithm to exchange keys for 3D ES or AES

  • Create a key pair generator:
    KeyPairGenerator kpg=KeyPairGenerator.getInstance("RSA");
  • Initialization key generator
    kpg.initialize(1024);
  • Generate key pairs
    KeyPair kp=kpg.genKeyPair( );
  • Getting public and private keys
    PublicKey pbkey=kp.getPublic( );
    `PrivateKey prkey=kp.getPrivate( );``
  • Create key agreement objects: KeyAgreement ka=KeyAgreement.getInstance("DH");
  • Initialize key agreement object: ka.init(prk);
  • Implement key agreement: ka.doPhase(pbk,true);
  • Generate shared information: byte [] sb = ka. generateSecret ();
  • Create a key: SecretKeySpec k=new SecretKeySpec(sb,"DESede");

Client

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.security.Key;
import java.util.Scanner;
import java.net.*;
public class Client5_4 {
    public static void main(String[] args) {
        String mode = "AES";
        //The client lets the user enter the suffix expression, and then converts the function of the suffix expression calling MyBC.java into the suffix expression, and sends the suffix expression to the server through the network.
        Scanner scanner = new Scanner(System.in);
        Socket mysocket;
        DataInputStream in = null;
        DataOutputStream out = null;
        try {
            mysocket = new Socket("127.0.0.1", 2010);
            in = new DataInputStream(mysocket.getInputStream());
            out = new DataOutputStream(mysocket.getOutputStream());
            System.out.println("Please enter the title to be calculated:");
            String formula = scanner.nextLine();
            String regex = ".*[^0-9|+|\\-|*|÷|(|)|\\s|/].*";
            if (formula.matches(regex)) {
                System.out.println("Illegal character input");
                System.exit(1);
            }
            String output = "";
            MyBC myBC = new MyBC();
            try {
                //Interfix to suffix
                output = myBC.getEquation(formula);
            } catch (ExprFormatException e) {
                System.out.println(e.getMessage());
                System.exit(1);
            }
            //Encryption of Suffix Expressions Using AES
            KeyGenerator kg = KeyGenerator.getInstance(mode);
            kg.init(128);
            SecretKey k = kg.generateKey();//Generating key
            byte mkey[] = k.getEncoded();
            Cipher cp = Cipher.getInstance(mode);
            cp.init(Cipher.ENCRYPT_MODE, k);
            byte ptext[] = output.getBytes("UTF8");
            byte ctext[] = cp.doFinal(ptext);

            //Pass the encrypted suffix expression to the server
            String out1 = B_H.parseByte2HexStr(ctext);
            out.writeUTF(out1);

            //Creating Public and Private Key of Client DH Algorithms
            Key_DH.createPubAndPriKey("Clientpub.txt","Clientpri.txt");

            //Pass the client public key to the server
            FileInputStream fp = new FileInputStream("Clientpub.txt");
            ObjectInputStream bp = new ObjectInputStream(fp);
            Key kp = (Key) bp.readObject();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(kp);
            byte[] kb = baos.toByteArray();
            String pop = B_H.parseByte2HexStr(kb);
            out.writeUTF(pop);
            Thread.sleep(1000);

            //Receiving server public key
            String push = in.readUTF();
            byte np[] = H_B.parseHexStr2Byte(push);
            ObjectInputStream ois = new ObjectInputStream (new ByteArrayInputStream (np));
            Key k2 = (Key)ois.readObject();;
            FileOutputStream f2 = new FileOutputStream("Serverpub.txt");
            ObjectOutputStream b2 = new ObjectOutputStream(f2);
            b2.writeObject(k2);

            //Generate shared information and AES keys
            SecretKeySpec key = KeyAgree.createKey("Serverpub.txt", "Clientpri.txt");

            //Encrypt the key of the encrypted suffix expression and pass it to the server
            cp.init(Cipher.ENCRYPT_MODE, key);
            byte ckey[] = cp.doFinal(mkey);
            String Key = B_H.parseByte2HexStr(ckey);
            out.writeUTF(Key);

            //Receiving Server Answer
            String s = in.readUTF();
            System.out.println("The client receives a reply from the server:" + s);
        } catch (Exception e) {
            System.out.println("Server disconnected" + e);
        }
    }
}

The server

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.Key;

public class Server5_4 {
    public static void main(String[] args) {
        String mode = "AES";
        ServerSocket serverForClient = null;
        Socket socketOnServer = null;
        DataOutputStream out = null;
        DataInputStream in = null;
        try{
            serverForClient = new ServerSocket(2010);
        }catch (IOException e1){
            System.out.println(e1);
        }
        String result;
        try{
            System.out.println("Waiting for customer call:");
            socketOnServer = serverForClient.accept();
            out = new DataOutputStream(socketOnServer.getOutputStream());
            in = new DataInputStream(socketOnServer.getInputStream());

            //Suffix expression after receiving encryption
            String cformula = in.readUTF();
            byte cipher[] = H_B.parseHexStr2Byte(cformula);


            //Receiving Client End Public Key
            String push = in.readUTF();
            byte np[] = H_B.parseHexStr2Byte(push);

            //Generate server common and private keys
            Key_DH.createPubAndPriKey("Serverpub.txt","Serverpri.txt");

            /*ObjectInputStream ois = new ObjectInputStream (new ByteArrayInputStream (np));
            Key k2 = (Key)ois.readObject();;
            FileOutputStream f2 = new FileOutputStream("Serverpub.txt");
            ObjectOutputStream b2 = new ObjectOutputStream(f2);
            b2.writeObject(k2);*/

            //Pass the server public key to the Client side
            FileInputStream fp = new FileInputStream("Serverpub.txt");
            ObjectInputStream bp = new ObjectInputStream(fp);
            Key kp = (Key) bp.readObject();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(kp);
            byte[] kb = baos.toByteArray();
            String pop = B_H.parseByte2HexStr(kb);
            out.writeUTF(pop);
            Thread.sleep(1000);

            //Generate shared information and AES keys
            SecretKeySpec key = KeyAgree.createKey("Serverpub.txt","Clientpri.txt");

            String k = in.readUTF();//Read the encrypted key
            byte[] encryptKey = H_B.parseHexStr2Byte(k);

            //Decrypt the encrypted key
            Cipher cp = Cipher.getInstance(mode);
            cp.init(Cipher.DECRYPT_MODE,key);
            byte decryptKey [] = cp.doFinal(encryptKey);

            //Decryption of ciphertext
            SecretKeySpec plainkey=new  SecretKeySpec(decryptKey,mode);
            cp.init(Cipher.DECRYPT_MODE, plainkey);
            byte []plain=cp.doFinal(cipher);

            //Compute the result of the suffix expression
            String formula = new String(plain);
            MyDC myDC = new MyDC();
            try{
                result = myDC.calculate(formula);
                //The suffix expression formula calls MyDC for evaluation
            }catch (ExprFormatException e){
                result = e.getMessage();
            }catch (ArithmeticException e0){
                result = "Divide Zero Error";
            }
            //Pass the calculation result to Client end
            out.writeUTF(result);
        }catch (Exception e){
            System.out.println("Customer disconnected"+e);
        }
    }
}

Task 5: The client calculates the summary value of client MD5 by MD5 algorithm and transmits it to the server. The server decrypts the plaintext and calculates the summary value of server MD5 by MD5 algorithm, and compares whether the two are equal.

  • Generate MessageDigest objects
    MessageDigest m=MessageDigest.getInstance("MD5");
  • Pass in the string to be computed
    m.update(x.getBytes("UTF8" ));
    x is the string to be computed
  • Compute message digest
    byte s[ ]=m.digest( );
  • Processing calculation results
String result="";
for (int i=0; i<s.length; i++){
       result+=Integer.toHexString((0x000000ff & s[i]) | 0xffffff00).substring(6);
  }

4. Screenshots of experimental results

Task 1

  • MyBC class test

  • MyDC class testing

Task 2

  • Enter the illegal character'a'

  • Continuous input of three operands

  • Continuous input of two operators

  • right parenthesis missing

  • Lack of left parentheses

  • The divisor is 0.

  • Normal condition

Task 3

Task 4

Task 5

4. Problems and Solutions in the Process of Experiments

  • Using byte []ctext=cp.doFinal(ptext); encrypting, the ciphertext generated is a byte [] array, but the parameters used when passing to the server should be String type, if String s = new String(ctext) is used directly; this construction method will appear javax. crypto. Illegal BlockSizeException: Input length must be multiple of 16 when decrypting with padded cipherpher.

  • Reason: Encrypted byte arrays cannot be forced into strings, in other words: strings and byte arrays are not reciprocal in this case; to avoid this situation, we need to make some revisions, we can consider converting binary data into hexadecimal representation.

  • Solution Convert ctext [] binary to hexadecimal and send it to the server. After the server receives it, it can convert hexadecimal to binary.
  • Client-side code:
String out1 = B_H.parseByte2HexStr(ctext);
out.writeUTF(out1);
  • Server side code:
String cformula = in.readUTF();//Read ciphertext
byte cipher[] = H_B.parseHexStr2Byte(cformula);

5. Experience

  • This experiment is based on the previous experiment three, adding the content of Chapter 12 client and server. It does not seem very difficult, but there are still a variety of errors in practice. Generally speaking, it is still necessary to actively knock code to really learn, and it will never be learned by looking at it alone.
  • Through this experiment, I also understand the benefits of blogging, that is, when I forget the previous knowledge, I can arouse them by looking at my blog.
  • To be continued...

Six. Code cloud link

VII. References

Keywords: PHP Java socket network Programming

Added by theBond on Sun, 26 May 2019 22:42:39 +0300