课程:Java程序与设计     班级:1353  姓 名:吴子怡   学号:20135313

小组成员: 20135113肖昱

成绩:             指导教师:娄嘉鹏       实验日期:2015.6.9

实验密级:          预习程度:         实验时间:15:30-18:00

仪器组次:          必修/选修:选修        实验序号:5

实验名称:Java网络编程及安全

实验目的与要求:结对编程,实现客户端和服务器之间数据的发送与接收,实现加解密和验证Hash函数值。

实验仪器:

名称

型号

数量

PC

DELL

1

Eclipse

1

 

一、实验内容

1.用TCP代码,实现服务器与客户端。

2.客户端与服务器连接

3.客户端中输入明文,利用DES算法加密,DES的秘钥用RSA公钥密码中服务器的公钥加密.

4.客户端用RSA公钥密码中服务器的私钥解密DES的,秘钥,用秘钥对密文进行解密,得出明文。

二.实验过程。

1.客户端 与服务器的连接。

服务器代码:

 
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.ServerSocket;
import java.net.Socket;
 
import java.security.SecureRandom;
 
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
public class ServerTest {
    int port = 8821;
 
    void start() {
        Socket s = null;
        try {
            ServerSocket ss = new ServerSocket(port);   //创建一个ServerSocket套接字对象,并绑定在8821端口上
            while (true) {
                // 选择进行传输的文件
                String filePath = "C:\\Users\\wzy\\Desktop\\服务器\\jiami.txt";
                File fi = new File(filePath);  //通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例
                System.out.println("文件长度:" + (int) fi.length());
 
                s = ss.accept();
                System.out.println("建立socket链接");
                DataInputStream dis = new DataInputStream(new BufferedInputStream(s.getInputStream()));   //DataInputStream:使用指定的底层 InputStream 创建一个 DataInputStream;
                dis.readByte();  //返回此输入流的下一个字节,以有符号 8 位 byte 的形式表示。
 
                DataInputStream fis = new DataInputStream(new BufferedInputStream(new FileInputStream(filePath)));
                DataOutputStream ps = new DataOutputStream(s.getOutputStream());//创建一个新的数据输出流,将数据写入指定基础输出流
 
 
                ps.writeUTF(fi.getName());
                ps.flush();
                ps.writeLong((long) fi.length());
                ps.flush();
 
                int bufferSize = 8192; //缓冲区,1k
                byte[] buf = new byte[bufferSize];
 
                while (true) {
                    int read = 0;
                    if (fis != null) {
                        read = fis.read(buf);
                    }
 
                    if (read == -1) {
                        break;
                    }
                    ps.write(buf, 0, read);
                }
                ps.flush();// 直到socket超时,导致数据不完整。                
                fis.close();
                s.close();                
                System.out.println("文件传输完成");
            }
 
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    public static void main(String arg[]) {
        new ServerTest().start();
    }
}

客户端Socket代码:

import java.net.*;
import java.io.*;
 
public class ClientSocket {
    private String ip;
 
    private int port;
 
    private Socket socket = null;
 
    DataOutputStream out = null;
 
    DataInputStream getMessageStream = null;
 
    public ClientSocket(String ip, int port) {
        this.ip = ip;
        this.port = port;
    }
 
    /** *//**
     * 创建socket连接
     * 
     * @throws Exception
     *             exception
     */
    public void CreateConnection() throws Exception {
        try {
            socket = new Socket(ip, port);
        } catch (Exception e) {
            e.printStackTrace();
            if (socket != null)
                socket.close();
            throw e;
        } finally {
        }
    }
 
    public void sendMessage(String sendMessage) throws Exception {
        try {
            out = new DataOutputStream(socket.getOutputStream());
            if (sendMessage.equals("Windows")) {
                out.writeByte(0x1);
                out.flush();
                return;
            }
            if (sendMessage.equals("Unix")) {
                out.writeByte(0x2);
                out.flush();
                return;
            }
            if (sendMessage.equals("Linux")) {
                out.writeByte(0x3);
                out.flush();
            } else {
                out.writeUTF(sendMessage);
                out.flush();
            }
        } catch (Exception e) {
            e.printStackTrace();
            if (out != null)
                out.close();
            throw e;
        } finally {
        }
    }
 
    public DataInputStream getMessageStream() throws Exception {
        try {
            getMessageStream = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
            return getMessageStream;
        } catch (Exception e) {
            e.printStackTrace();
            if (getMessageStream != null)
                getMessageStream.close();
            throw e;
        } finally {
        }
    }
 
    public void shutDownConnection() {
        try {
            if (out != null)
                out.close();
            if (getMessageStream != null)
                getMessageStream.close();
            if (socket != null)
                socket.close();
        } catch (Exception e) {
 
        }
    }
}

客户端Test代码:

 
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
 
public class ClientTest {
    private ClientSocket cs = null;
 
    private String ip = "192.168.253.1";// 设置成服务器IP
 
    private int port = 8821;
 
    private String sendMessage = "Windwos";
 
    public ClientTest() {
        try {
            if (createConnection()) {
                sendMessage();
                getMessage();
            }
 
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
 
    private boolean createConnection() {
        cs = new ClientSocket(ip, port);
        try {
            cs.CreateConnection();
            System.out.print("连接服务器成功!" + "\n");
            return true;
        } catch (Exception e) {
            System.out.print("连接服务器失败!" + "\n");
            return false;
        }
 
    }
 
    private void sendMessage() {
        if (cs == null)
            return;
        try {
            cs.sendMessage(sendMessage);
        } catch (Exception e) {
            System.out.print("发送消息失败!" + "\n");
        }
    }
 
    private void getMessage() {
        if (cs == null)
            return;
        DataInputStream inputStream = null;
        try {
            inputStream = cs.getMessageStream();
        } catch (Exception e) {
            System.out.print("接收消息缓存错误\n");
            return;
        }
 
        try {
            //本地保存路径,文件名会自动从服务器端继承而来。
            String savePath = "E:\\客户端\\";
            int bufferSize = 8192;
            byte[] buf = new byte[bufferSize];
            int passedlen = 0;
            long len=0;
            
            savePath += inputStream.readUTF();
            DataOutputStream fileOut = new DataOutputStream(new BufferedOutputStream(new BufferedOutputStream(new FileOutputStream(savePath))));
            len = inputStream.readLong();
            
            System.out.println("文件的长度为:" + len + "\n");
            System.out.println("开始接收文件!" + "\n");
                    
            while (true) {
                int read = 0;
                if (inputStream != null) {
                    read = inputStream.read(buf);
                }
                passedlen += read;
                if (read == -1) {
                    break;
                }
                //下面进度条本为图形界面的prograssBar做的,这里如果是打文件,可能会重复打印出一些相同的百分比
                System.out.println("文件接收了" +  (passedlen * 100/ len) + "%\n");
                fileOut.write(buf, 0, read);
            }
            System.out.println("接收完成,文件存为" + savePath + "\n");
 
            fileOut.close();
        } catch (Exception e) {
            System.out.println("接收消息错误" + "\n");
            return;
        }
    }
 
    public static void main(String arg[]) {
        new ClientTest();
    }
}

在这只做简单代码展示,具体传输文件见下述步骤。

2.用DES加密明文,并传输给服务器密文。

DES加密代码:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.SecureRandom;
 
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
 
public class DESJiaMi {
    public static void main(String[] args) throws Exception {
 
        // DES算法要求有一个可信任的随机数源
        SecureRandom sr = new SecureRandom();
        // 获得密匙数据
        FileInputStream fi = new FileInputStream(new File("key.txt"));
        byte rawKeyData[] = new byte[fi.available()];
        fi.read(rawKeyData);
        fi.close();
        // 从原始密匙数据创建DESKeySpec对象
        DESKeySpec dks = new DESKeySpec(rawKeyData);
        // 创建一个密匙工厂,然后用它把DESKeySpec转换成一个SecretKey对象
        SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(dks);
        // Cipher对象实际完成加密操作
        Cipher cipher = Cipher.getInstance("DES");
        // 用密匙初始化Cipher对象
        cipher.init(Cipher.ENCRYPT_MODE, key, sr);
        // 现在,获取要加密的文件数据
        FileInputStream fi2 = new FileInputStream(new File("lib.txt"));
        byte data[] = new byte[fi2.available()];
        fi2.read(data);
        fi2.close();
        // 正式执行加密操作
        byte encryptedData[] = cipher.doFinal(data);
        // 用加密后的数据文件
        FileOutputStream fo = new FileOutputStream(new File("jiami.txt"));
        fo.write(encryptedData);
        fo.close();
new ServerTest().start();
    }
}

DES解密代码:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.SecureRandom;
 
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
 
public class DESJieMi {
    public static void main(String[] args) throws Exception {
new ClientTest();
 
        // DES算法要求有一个可信任的随机数源
        SecureRandom sr = new SecureRandom();
        // 获得密匙数据
        FileInputStream fi = new FileInputStream(new File("key.txt"));
        byte rawKeyData[] = new byte[fi.available()];// = new byte[5];
        fi.read(rawKeyData);
        fi.close();
        // 从原始密匙数据创建一个DESKeySpec对象
        DESKeySpec dks = new DESKeySpec(rawKeyData);
        // 创建一个密匙工厂,然后用它把DESKeySpec对象转换成一个 SecretKey对象
        SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(dks);
        // Cipher对象实际完成解密操作
        Cipher cipher = Cipher.getInstance("DES");
        // 用密匙初始化Cipher对象
        cipher.init(Cipher.DECRYPT_MODE, key, sr);
        // 现在,获取数据并解密
        FileInputStream fi2 = new FileInputStream(new File("jiami.txt"));
        byte encryptedData[] = new byte[fi2.available()];
        fi2.read(encryptedData);
        fi2.close();
        // 正式执行解密操作
        byte decryptedData[] = cipher.doFinal(encryptedData);
        // 这时把数据还原成原有的类文件
        FileOutputStream fo = new FileOutputStream(new File("jiemi.txt"));
        fo.write(decryptedData);
 
    }
}
密钥 key.txt 

lib.txt表示明文

通过服务器与客户端相连,服务器将加密后的文件jiami.txt传输给客户端待用。

加密后的密文 jiami.txt

3.RSA加密密钥,传输,RSA解密获得密钥。

服务器使用已给出的代码加密密钥。原理相近,不作截图展示。

代码为老师上课在Java学习群中给出的代码包,也不作截图展示。

将所加密内容发给客户端。并进行解密,得到客户端解密后的密钥。

4.用密钥解密密文。

解密代码所生成的jiemi.txt。

【实验体会】

本次实验中大部分代码都是老师既定给好的,而我们的主要任务是对要实现的传输、加解密、连接等进行处理衔接,让我们从编程一跃提升到有目的性的实战。这次实验主要分为三个部分,一是多线程客户端和服务器的连接,而是RSA公钥加密,三是DES加密。我认为,这些内容都是要跨科目实现的,不管是密码学还是计网,都在这过程中起着很大的作用。然而,实验中也遇到不少问题,也较为琐碎。和搭档讨论后,对方给了我很多指导,也逐渐能够看到实验结果离我越来越近。以后还是需要更多地寻找实验操作,多和在Java方面学习更深入的同学探讨来提升自己的能力。

步骤

耗时

百分比

需求分析

30m

30%

设计

10m

10%

代码实现

10m

10%

测试

40m

40%

分析总结

10m

10%

20135313_exp5的更多相关文章

随机推荐

  1. 前端基础-jQuery的最常用的的方法each、data、

    阅读目录 each inArray get index data 一.jQuery中each方法的应用 jQuery中有个很重要的核心方法each,大部分jQuery方法在内部都会调用each,其主要 ...

  2. css动画Demo---水波动画和边框动画

    先上效果图: 水波动画: 边框动画: 1.水波动画 实现代码 <!DOCTYPE html> <html lang="en"> <head> & ...

  3. 【大数据实战】Logstash采集->Kafka->ElasticSearch检索

    1. Logstash概述 Logstash的官网地址为:https://www.elastic.co/cn/products/logstash,以下是官方对Logstash的描述. Logstash ...

  4. python 数据类型、进制转换

    数据类型 存储单位 最小单位是bit,表示二进制的0或1,一般写作b 最小的存储单位是字节,用byte表示,1B = 8b 1024B = 1KB 1024KB = 1MB 1024MB = 1GB ...

  5. ruby安装devkit

    双击下载文件,指定解压路径,路径中不能有空格.如C:\DevKit,这个路径就是<DEVKIT_INSTALL_DIR>. > cd <DEVKIT_INSTALL_DIR&g ...

  6. Java学习笔记三十一:Java 包(package)

    Java 包(package) 一:包的作用: 如果我们在使用eclipse等工具创建Java工程的时候,经常会创建包,那么,这个包是什么呢. 为了更好地组织类,Java 提供了包机制,用于区别类名的 ...

  7. 解决「matplotlib 图例中文乱码」问题

    在学习用 matplotlib 画图时遇到了中文显示乱码的问题,在网上找了很多需要修改配置的方法,个人还是喜欢在代码里修改. 解决方法如下: 在第2.3行代码中加上所示代码即可. import mat ...

  8. Mac使用bootcamp安装win系统花屏解决方法

    15年11'乞丐版air装win屏幕花屏,很郁闷,先后找了网上很多方法,最终总结出了一个比较折中的方法,不玩游戏不使用大型3D的可以参考. 1 花屏现象 2 解决方法 2.1 禁用驱动 2.2 使用M ...

  9. java入门---循环结构 - for, while 及 do...while&break&continue

        顺序结构的程序语句只能被执行一次.如果您想要同样的操作执行多次,,就需要使用循环结构.Java中有三种主要的循环结构: while 循环 do…while 循环 for 循环     在Jav ...

  10. 20155218 2016-2017-2 《Java程序设计》第9周学习总结

    20155218 2016-2017-2 <Java程序设计>第9周学习总结 教材学习内容总结 JDBC全名Java DataBase Connectivity,是java联机数据库的标准 ...