zoukankan      html  css  js  c++  java
  • 实验五 Java网络编程及安全

    实验内容

    1.掌握Socket程序的编写;

    2.掌握密码技术的使用;

    3.设计安全传输系统。

    实验步骤

    1. 基于Java Socket实现安全传输

    2. 基于TCP实现客户端和服务器,结对编程一人负责客户端,一人负责服务器

    3. 使用Git进行版本控制

    4. 选择对称算法进行数据加解密.

    5. 选择非对称算法对对称加密密钥进行密钥分发.

    6. 选择合适的Hash算法进行完整性验证.

    7. 选择合适的算法对Hash值进行签名/验证.

    发送方使用DES对明文加密,属于对称加密算法,加密速度快但是初始密钥分发不能保证其安全性,使用RSE加密DES的密钥信息,然后再用对称加密,可以解决密钥分发问题,又能保障加密速度。

    接收方接到信息后,使用对称解密算法,用RSA解密密钥信息,首先发送端用Hash函数产生足以区别文件的摘要值,再由接收端使用相同的Hash函数自行产生文件摘要,并比对与先前解密结果是否相符。

    实验代码

    (客户端)

    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();

     

     

     

               // 创建连接特定服务器的指定端口的Socket对象

     

               Socket socket = new Socket("192.168.80.1", 8028);

     

               // 网络输入流

     

               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;

     

        }

     

    }

    (服务端)

    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(8029);// 创建服务器套接字

     

               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;

     

        }

     

    }

     

    出现的问题及总结

    通过ipconfig在命令行中查看IPv4的地址输入Socket中,显示无法连接,通过变化端口再次连接客户端向服务器发送消息,试过几次不同的端口最后显示匹配成功。问题在于如何在用完端口后及时关闭。

    在相同的无线网下可以匹配成功并收到客户端的消息,在不同的无线网下IPv4地址不同不能连接。

     

     

     

  • 相关阅读:
    RC4加密
    树莓派3B+学习笔记:13、不间断会话服务screen
    树莓派3B+学习笔记:12、安装FireFox浏览器
    树莓派3B+学习笔记:11、查看硬件信息
    树莓派3B+学习笔记:10、使用SSH连接树莓派
    树莓派3B+学习笔记:9、更改软件源
    树莓派3B+学习笔记:8、安装MySQL
    树莓派3B+学习笔记:7、挂载exfat格式U盘和NTFS格式移动硬盘
    树莓派3B+学习笔记:6、安装TeamViewer
    树莓派3B+学习笔记:5、安装vim
  • 原文地址:https://www.cnblogs.com/20159214sn/p/4909029.html
Copyright © 2011-2022 走看看