zoukankan      html  css  js  c++  java
  • 20145107 《Java程序设计》第五次实验报告

    实验简述:

    在本周,我们进行了Java的第五次试验,本次实验的主要内容是结对编程。本次实验的大体过程是:

    • 1.先进行Java的客户端与服务端的代码编写。结对是两个人,一人负责客户端,一人负责服务端。
    • 2.利用加解密代码包,编译运行代码,客户端加密,服务器解密。
    • 3.客户端加密明文后将密文通过TCP发送。
    • 4.在本次的代码编写上,要求代码可以实现两者之间的数据传输,在代码传输的基础上加上一定的加密过程,并按照网络的应答机制回复相应的信息。
      在本次试验中我负责的是服务端。同组同学屠轶成负责的是客户端
      20145110屠轶成博客链接

    实验过程:

    • 1.在我自己的电脑上,通过分析老师的代码后自己又改了一些,实现了一个服务端的代码这个服务器可以帮助两者之间的数据传输,并对数据传传输的结果情况进行反馈。
      具体的代码如下:
    package exp5;
    
    
    
    import java.net.*;
    
    import java.io.*;
    
    import java.security.*;
    
    import java.security.spec.*;
    
    import javax.crypto.*;
    
    import javax.crypto.spec.*;
    
    import javax.crypto.interfaces.*;
    
    import java.security.interfaces.*;
    
    import java.math.*;
    
    
    
    public class Server {
    
        public static void main(String srgs[]) throws Exception {
    
            ServerSocket sc = null;
    
            Socket socket = null;
    
            try {
    
                sc = new ServerSocket(2530);// 创建服务器套接字
    
                System.out.println("端口号:" + sc.getLocalPort());
    
                System.out.println("服务器成功启动");
    
                socket = sc.accept(); // 等待客户端连接
    
                System.out.println("成功建立连接");
    
                // 获得网络输入流对象的引用
    
                BufferedReader in = new BufferedReader(new InputStreamReader(
    
                        socket.getInputStream()));
    
                // //获得网络输出流对象的引用
    
                PrintWriter out = new PrintWriter(new BufferedWriter(
    
                        new OutputStreamWriter(socket.getOutputStream())), true);
    
    
    
                String aline2 = in.readLine();
    
                BigInteger c = new BigInteger(aline2);
    
                FileInputStream f = new FileInputStream("Skey_RSA_priv.dat");
    
                ObjectInputStream b = new ObjectInputStream(f);
    
                RSAPrivateKey prk = (RSAPrivateKey) b.readObject();
    
                BigInteger d = prk.getPrivateExponent();
    
                BigInteger n = prk.getModulus();
    
                BigInteger m = c.modPow(d, n);
    
                byte[] keykb = m.toByteArray();
    
                String aline = in.readLine();// 读取客户端传送来的数据
    
                byte[] ctext = parseHexStr2Byte(aline);
    
                Key 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); // 通过网络输出流返回结果给客户端
    
                String aline3 = in.readLine();
    
                String x = p;
    
                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);
    
    
    
                if (aline3.equals(result)) {
    
                    System.out.println("信息核对无误");
    
                }
    
    
    
                out.println("信息核对无误");
    
                out.close();
    
                in.close();
    
                sc.close();
    
            } catch (Exception e) {
    
                System.out.println(e);
    
            }
    
        }
    
    
    
        public static String parseByte2HexStr(byte buf[]) {
    
            StringBuffer sb = new StringBuffer();
    
            for (int i = 0; i < buf.length; i++) {
    
                String hex = Integer.toHexString(buf[i] & 0xFF);
    
                if (hex.length() == 1) {
    
                    hex = '0' + hex;
    
                }
    
                sb.append(hex.toUpperCase());
    
            }
    
            return sb.toString();
    
        }
    
    
    
        public static byte[] parseHexStr2Byte(String hexStr) {
    
            if (hexStr.length() < 1)
    
                return null;
    
            byte[] result = new byte[hexStr.length() / 2];
    
            for (int i = 0; i < hexStr.length() / 2; i++) {
    
                int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
    
                int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2),
    
                        16);
    
                result[i] = (byte) (high * 16 + low);
    
            }
    
            return result;
    
        }
    
    }
    
    

    运行服务器后的效果如下:

    要想实现数据的加密传输,则要有一个客户端的程序,这个程序中有IP地址的设置问题:

    在代码中有一个IP地址的设置问题,要想知道自己的IP地址,可以使用cmd命令行来实现:

    在命令行中使用ipconfig命令:

    代码如下:

    package exp5;
    
    import java.net.*;
    
    import java.io.*;
    
    import java.security.*;
    
    import javax.crypto.*;
    
    import javax.crypto.spec.*;
    
    import java.security.spec.*;
    
    import javax.crypto.interfaces.*;
    
    import java.security.interfaces.*;
    
    import java.math.*;
    
    public class Client {
    
        public static void main(String srgs[]) throws Exception{
    
            try {
    
                KeyGenerator kg=KeyGenerator.getInstance("DESede");
    
                kg.init(168);
    
                SecretKey k=kg.generateKey( );
    
                byte[] ptext2=k.getEncoded();
    
                //String kstr=parseByte2HexStr(kb);
    
                //创建连接特定服务器的指定端口的Socket对象
    
                Socket socket = new Socket("222.28.131.90",2530);
    
                //获得从服务器端来的网络输入流
    
                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    
                //获得从客户端向服务器端输出数据的网络输出流
    
                PrintWriter out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
    
                //创建键盘输入流,以便客户端从键盘上输入信息
    
                BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
    
    
    
                FileInputStream f3=new FileInputStream("Skey_RSA_pub.dat");
    
                ObjectInputStream b2=new ObjectInputStream(f3);
    
                RSAPublicKey pbk=(RSAPublicKey)b2.readObject( );
    
                BigInteger e=pbk.getPublicExponent();
    
                BigInteger n=pbk.getModulus();
    
                BigInteger m=new BigInteger(ptext2);
    
                BigInteger c=m.modPow(e,n);
    
                String cs=c.toString( );
    
                out.println(cs);  //通过网络传送到服务器
    
                System.out.print("输入发送信息:");
    
                String s=stdin.readLine(); //从键盘读入待发送的数据
    
                Cipher cp=Cipher.getInstance("DESede");
    
                cp.init(Cipher.ENCRYPT_MODE, k);
    
                byte ptext[]=s.getBytes("UTF8");
    
                byte ctext[]=cp.doFinal(ptext);
    
                String str=parseByte2HexStr(ctext);
    
                out.println(str);  //通过网络传送到服务器
    
                String x=s;
    
                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);
    
                str=in.readLine();//从网络输入流读取结果
    
                System.out.println( "服务器反馈为:"+str); //输出服务器返回的结果
    
            }
    
            catch (Exception e) {
    
                System.out.println(e);
    
            }
    
            finally{
    
            }
    
    
    
        }
    
        public static String parseByte2HexStr(byte buf[]) {
    
            StringBuffer sb = new StringBuffer();
    
            for (int i = 0; i < buf.length; i++) {
    
                String hex = Integer.toHexString(buf[i] & 0xFF);
    
                if (hex.length() == 1) {
    
                    hex = '0' + hex;
    
                }
    
                sb.append(hex.toUpperCase());
    
            }
    
            return sb.toString();
    
        }
    
        public static byte[] parseHexStr2Byte(String hexStr) {
    
            if (hexStr.length() < 1)
    
                return null;
    
            byte[] result = new byte[hexStr.length()/2];
    
            for (int i = 0;i< hexStr.length()/2; i++) {
    
                int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);
    
                int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);
    
                result[i] = (byte) (high * 16 + low);
    
            }
    
            return result;
    
        }
    
    }
    
    

    数据传输时,运行客户端程序,输入你想要传输的数据:

    数据传输完成后,在相应的服务端就会有相应的结果和反馈信息:

    本周代码上传:

    实验心得:

    在代码运行的时候,因为涉及到了RSA的程序,程序老是运行不出来,后来,又加了一个Skey_RSA的Java文件,程序得以成功运行。而且,在一台电脑上也可以实现客户端和服务端的同时运行。

  • 相关阅读:
    【第40套模拟题】【noip2011_mayan】解题报告【map】【数论】【dfs】
    【模拟题(63550802...)】解题报告【贪心】【拓扑排序】【找规律】【树相关】
    【模拟题(电子科大MaxKU)】解题报告【树形问题】【矩阵乘法】【快速幂】【数论】
    IMemoryBufferReference and IMemoryBufferByteAccess
    SoftwareBitmap and BitmapEncoder in Windows.Graphics.Imaging Namespace
    Windows UPnP APIs
    编译Android技术总结
    Windows函数转发器
    Two Ways in Delphi to Get IP Address on Android
    Delphi Call getifaddrs and freeifaddrs on Android
  • 原文地址:https://www.cnblogs.com/20145107lcd/p/5471320.html
Copyright © 2011-2022 走看看