课程: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. CF451E Devu and Flowers(组合数)

    题目描述 Devu想用花去装饰他的花园,他已经购买了n个箱子,第i个箱子有fi朵花,在同一个的箱子里的所有花是同种颜色的(所以它们没有任何其他特征).另外,不存在两个箱子中的花是相同颜色的. 现在De ...

  2. [WCF学习笔记] 我的WCF之旅(1):创建一个简单的WCF程序

    近日学习WCF,找了很多资料,终于找到了Artech这个不错的系列.希望能从中有所收获. 本文用于记录在学习和实践WCF过程中遇到的各种基础问题以及解决方法,以供日后回顾翻阅.可能这些问题都很基础,可 ...

  3. mysql如何把一个表直接拷贝到一个新的表

    一:在新表已经建立好的情况下 1,拷贝所有的字段 insert into new_table select * from old_table 2,拷贝部分字段表 insert into new_tab ...

  4. Delphi Android USB声明文件

    自己转的比较全面的USB声明文件: unit Androidapi.JNI.USB; interface uses AndroidAPI.JNIBridge, Androidapi.JNI.JavaT ...

  5. Linux--ps及top、ls命令

    day8  ps系统管理命令 ps是强大的后台进程检测命令 格式:ps [options] [--help] 选项参数: 1.-a :显示所有进程,包括PID等,包括其他用户运行的程序 2.-ef:显 ...

  6. 轻松解决U盘加密问题

    很多小伙伴常常会遇到这样的问题,比如说有朋友或者同事想借用你的u盘,处于人情世故你又不得不借,但是又不喜欢自己的文件被别人看到或者担心丢失或被修改,在此提供一种给u盘加密或者给u盘里的文件加密的方法. ...

  7. 转:c# Linq 的分页[转]

    转:http://www.cnblogs.com/leleroyn/archive/2008/05/14/1196811.html 很多学习Linq的朋友肯定有自己所不同的方法,考虑这个问题我所想到的 ...

  8. JQuery补充——获取与设置表单值

    //写jQuery代码时注意前面一定要记得加$(function(){});,在文档加载完成后进行代码的编写 使用jQuery的表单对象属性来选择被选中的项::checked,详见文档选择器部分 根据 ...

  9. 20155226 2016-2017-2 《Java程序设计》课程总结

    20155226 2016-2017-2<Java程序设计>课程总结 每周作业链接汇总 预备作业1:师生关系 预备作业2:优秀技能经验 预备作业3:虚拟机linux初接触 第一周学习总结: ...

  10. 第三次预作业20155231邵煜楠:虚拟机上的Linux学习

    java第三次预作业--虚拟机初体验(学习记录) 学习在笔记本上安装Linux操作系统 通过老师给予的官网链接,下载了VirtualBox-5.1.14-112924-win和Ubuntu-16.04 ...