Java实现批量文件加密

一、题目要求:

用Java实现一个文件批量加密解密工具,实现以下功能:

1. 要有图形界面。

2. 能够通过界面设置一个目录,软件对该目录下的所有文件进行加密或解密(使用对称或非对称加密算法)。

    加密后删除原文件并保留加密后的文件,对加密后的文件进行解密后,删除加密后的文件,保留解密出的原文件。

3. 加密和解密时,如何选择密钥?

    选定一张图片,求出它的MD5值,并用该值生成加密密钥。

4. 写一个验证程序,该程序完成:

    (1)对加密前的所有文件,逐一求出MD5值,并记录到文件A中;

    (2)然后对所有文件先加密后解密;再用该验证程序逐一求出解密后文件的MD5值,并记录到文件B中;

    (3)比较文件A和文件B的内容,相同则返回true,否则返回false。


二、题目解答程序源代码如下

主程序类:

package com.student.main;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.security.Key;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JSpinner;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;

import com.student.utils.FileMd5Utils;

import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;

/**
 * 获取文件列表的过滤器
 * 
 * @author myname
 */
public class EnDeFiles extends JFrame {

	/** 
     *  
     */
	private static final long serialVersionUID = 4534371106024773867L;

	private final class ExtNameFileFilter implements FileFilter {
		private String extName; // 文件扩展名

		public ExtNameFileFilter(String extName) {
			this.extName = extName;// 保存文件扩展名
		}

		@Override
		public boolean accept(File pathname) {
			// 过滤文件扩展名
			if (pathname.getName().toUpperCase()
					.endsWith(extName.toUpperCase()))
				return true;
			return false;
		}
	}

	private JPanel contentPane;
	private JTextField forderField;
	private JTextField templetField;
	private File dir;
	private JTable table;
	private JTextField extNameField;
	private JSpinner startSpinner;
	
	private File md5file1;
	private File md5file2;
	
	private String md5Origin;
	

	/**
	 * Launch the application.主函数
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					EnDeFiles frame = new EnDeFiles(); // 创建窗体
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public EnDeFiles() {
		setResizable(false);
		setTitle("文件批量加密解密");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 383, 409);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		GridBagLayout gbl_contentPane = new GridBagLayout(); // 创建布局
		gbl_contentPane.columnWidths = new int[] { 72, 54, 60, 87, 91, 0 }; // 列宽
		gbl_contentPane.rowHeights = new int[] { 25, 25, 10, 25, 24, 25, 2, // 高
				216, 0 };
		gbl_contentPane.columnWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, // 列权重
				Double.MIN_VALUE };
		gbl_contentPane.rowWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, // 行权重
				0.0, 0.0, 0.0, Double.MIN_VALUE };
		contentPane.setLayout(gbl_contentPane); // 设定布局

		JLabel label = new JLabel();
		label.setText("文件加密解密:");
		GridBagConstraints gbc_label = new GridBagConstraints();
		gbc_label.fill = GridBagConstraints.VERTICAL;
		gbc_label.insets = new Insets(0, 0, 5, 5);
		gbc_label.gridwidth = 3;
		gbc_label.gridx = 1;
		gbc_label.gridy = 0;
		contentPane.add(label, gbc_label);

		JLabel label_1 = new JLabel();
		label_1.setText("文件路径:");
		GridBagConstraints gbc_label_1 = new GridBagConstraints();
		gbc_label_1.anchor = GridBagConstraints.EAST;
		gbc_label_1.fill = GridBagConstraints.VERTICAL;
		gbc_label_1.insets = new Insets(0, 0, 5, 5);
		gbc_label_1.gridx = 0;
		gbc_label_1.gridy = 1;
		contentPane.add(label_1, gbc_label_1);

		forderField = new JTextField();
		forderField.setText("");
		GridBagConstraints gbc_forderField = new GridBagConstraints();
		gbc_forderField.fill = GridBagConstraints.HORIZONTAL;
		gbc_forderField.insets = new Insets(0, 0, 5, 5);
		gbc_forderField.gridwidth = 3;
		gbc_forderField.gridx = 1;
		gbc_forderField.gridy = 1;
		contentPane.add(forderField, gbc_forderField);

		// ----------------选取目录,浏览目录下文件------------------
		JButton button = new JButton();
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				do_button_actionPerformed(e);
			}
		});
		button.setText("浏览");
		GridBagConstraints gbc_button = new GridBagConstraints();
		gbc_button.anchor = GridBagConstraints.NORTHWEST;
		gbc_button.insets = new Insets(0, 0, 5, 0);
		gbc_button.gridx = 4;
		gbc_button.gridy = 1;
		contentPane.add(button, gbc_button);

		JSeparator separator_1 = new JSeparator();
		GridBagConstraints gbc_separator_1 = new GridBagConstraints();
		gbc_separator_1.fill = GridBagConstraints.BOTH;
		gbc_separator_1.insets = new Insets(0, 0, 5, 0);
		gbc_separator_1.gridwidth = 5;
		gbc_separator_1.gridx = 0;
		gbc_separator_1.gridy = 2;
		contentPane.add(separator_1, gbc_separator_1);

		// JLabel label_5 = new JLabel();
		// label_5.setText("使用#可以指定数字计数所占的位置,使用*可以插入原文件名:");
		// GridBagConstraints gbc_label_5 = new GridBagConstraints();
		// gbc_label_5.fill = GridBagConstraints.VERTICAL;
		// gbc_label_5.insets = new Insets(0, 0, 5, 0);
		// gbc_label_5.gridwidth = 5;
		// gbc_label_5.gridx = 0;
		// gbc_label_5.gridy = 3;
		// contentPane.add(label_5, gbc_label_5);

		// JLabel label_2 = new JLabel();
		// label_2.setText("  扩展名:");
		// GridBagConstraints gbc_label_2 = new GridBagConstraints();
		// gbc_label_2.fill = GridBagConstraints.HORIZONTAL;
		// gbc_label_2.insets = new Insets(0, 0, 5, 5);
		// gbc_label_2.gridx = 2;
		// gbc_label_2.gridy = 5;
		// contentPane.add(label_2, gbc_label_2);

		// 创建开始加密按钮---------------------------------
		JButton startEncryptButton = new JButton();
		startEncryptButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					do_startEncryptButton_actionPerformed(e);
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});

		// 创建开始解密按钮---------------------------------

		JButton startDecryptButton = new JButton();
		startDecryptButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					do_startDecryptButton_actionPerformed(e);
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});

		// extNameField = new JTextField();
		// extNameField.setText("jpg");
		// GridBagConstraints gbc_extNameField = new GridBagConstraints();
		// gbc_extNameField.fill = GridBagConstraints.HORIZONTAL;
		// gbc_extNameField.insets = new Insets(0, 0, 5, 5);
		// gbc_extNameField.gridx = 3;
		// gbc_extNameField.gridy = 5;
		// contentPane.add(extNameField, gbc_extNameField);
		startEncryptButton.setText("开始加密");
		GridBagConstraints gbc_startButton = new GridBagConstraints();
		gbc_startButton.anchor = GridBagConstraints.NORTH;
		gbc_startButton.insets = new Insets(0, 0, 5, 0);
		gbc_startButton.gridx = 0;
		gbc_startButton.gridy = 5;
		contentPane.add(startEncryptButton, gbc_startButton);

		startDecryptButton.setText("开始解密");
		GridBagConstraints gbc_startDeButton = new GridBagConstraints();

		gbc_startDeButton.fill = GridBagConstraints.HORIZONTAL;
		gbc_startDeButton.insets = new Insets(0, 0, 5, 0);
		gbc_startDeButton.gridx = 4;
		gbc_startDeButton.gridy = 5;
		contentPane.add(startDecryptButton, gbc_startDeButton);
		// contentPane.add(startDecryptButton);

		JSeparator separator_2 = new JSeparator();
		GridBagConstraints gbc_separator_2 = new GridBagConstraints();
		gbc_separator_2.anchor = GridBagConstraints.NORTH;
		gbc_separator_2.fill = GridBagConstraints.HORIZONTAL;
		gbc_separator_2.insets = new Insets(0, 0, 5, 0);
		gbc_separator_2.gridwidth = 5;
		gbc_separator_2.gridx = 0;
		gbc_separator_2.gridy = 6;
		contentPane.add(separator_2, gbc_separator_2);

		JScrollPane scrollPane = new JScrollPane();
		GridBagConstraints gbc_scrollPane = new GridBagConstraints();
		gbc_scrollPane.fill = GridBagConstraints.BOTH;
		gbc_scrollPane.gridwidth = 5;
		gbc_scrollPane.gridx = 0;
		gbc_scrollPane.gridy = 7;
		contentPane.add(scrollPane, gbc_scrollPane);

		table = new JTable();
		table.setModel(new DefaultTableModel(new Object[][] {}, new String[] {
				"旧文件名", "新文件名" }));
		scrollPane.setViewportView(table);
	}

	/**
	 * 浏览按钮的事件处理方法
	 * 
	 * @param e
	 */
	protected void do_button_actionPerformed(ActionEvent e) {
		JFileChooser chooser = new JFileChooser();// 创建文件选择器
		// 设置只选择文件夹
		chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		int option = chooser.showOpenDialog(this);// 显示打开对话框
		if (option == JFileChooser.APPROVE_OPTION) {
			dir = chooser.getSelectedFile();// 获取选择的文件夹
		} else {
			dir = null;
		}
		forderField.setText(dir + "");// 显示文件夹信息
	}

	/**
	 * 开始按钮的事件处理方法
	 * 
	 * @param e
	 */
	protected void do_startButton_actionPerformed(ActionEvent e) {

	}

	protected void do_startEncryptButton_actionPerformed(ActionEvent e)
			throws Exception {
		// 获取表格数据模型
		DefaultTableModel model = (DefaultTableModel) table.getModel();
		model.setRowCount(0);// 清除表格数据

		// 获取文件中文件列表数组
		File[] files = dir.listFiles();

		md5file1 = new File("D:/md5Origin.txt");
		PrintStream ps = new PrintStream(new FileOutputStream(md5file1));

		for (File file : files) {// 变量文件数组

			// System.out.println("文件名: " + file.getName());
			String filename = file.getName().substring(0,
					file.getName().lastIndexOf("."));
			String extname = file.getName().substring(
					file.getName().lastIndexOf("."));
			String enFilename = "en" + filename + extname;
			// System.out.println("加密后的文件名: " + enFilename);

			String path = file.getPath();
			// System.out.println("全名: " + path);

			String purePath = path.substring(0, path.lastIndexOf("\\") + 1);
			// System.out.println("路径名:" + purePath);

			// 使用图片生成密钥
			String keyFileName = "G:/key.png";
			String md5KeyStr = FileMd5Utils.getFileMD5String(keyFileName);
			Key key = FileMd5Utils.getKey(md5KeyStr);

			// 原文件md5值
			md5Origin = FileMd5Utils.getFileMD5String(path);

			// 写入文件md5文件中
			// ps.append("\n");
			ps.append(md5Origin);

			// 加密文件
			FileMd5Utils.encrypt(path, purePath + enFilename, key);

			String name = purePath + enFilename;
			// System.out.println(name);

			// 把文件的旧名称与新名称添加到表格的数据模型
			model.addRow(new String[] { file.getName(), name });

			// 删除原文件
			if (file.exists()) {
				// System.gc();
				boolean flag = file.delete();

				// System.out.println(flag);
				System.gc();
				String filepath = file.getPath();
				Runtime rt = Runtime.getRuntime();
				try {

					rt.exec("cmd   /c   del   " + filepath);

				} catch (IOException e1) {
					e1.printStackTrace();
				}
			} else {
				System.out.println("文件不存在!");
			}

		}

	}

	protected void do_startDecryptButton_actionPerformed(ActionEvent e)
			throws Exception {
		// 获取表格数据模型
		DefaultTableModel model = (DefaultTableModel) table.getModel();
		model.setRowCount(0);// 清除表格数据

		// 获取文件中文件列表数组
		File[] files = dir.listFiles();

		md5file2 = new File("D:/md5Origin2.txt");
		PrintStream ps = new PrintStream(new FileOutputStream(md5file2));

		for (File file : files) {// 变量文件数组

			// System.out.println("文件名: " + file.getName());
			String filename = file.getName().substring(0,
					file.getName().lastIndexOf("."));
			String extname = file.getName().substring(
					file.getName().lastIndexOf("."));

			// String enFilename = "en" + filename + extname;
			String deFilename = "de" + filename + extname;

			// System.out.println("加密并解密后的文件名: " + deFilename);

			String path = file.getPath();
			// System.out.println("全名: " + path);

			String purePath = path.substring(0, path.lastIndexOf("\\") + 1);
			// System.out.println("路径名:" + purePath);

			// 使用图片生成密钥
			String keyFileName = "G:/key.png";
			String md5KeyStr = FileMd5Utils.getFileMD5String(keyFileName);
			Key key = FileMd5Utils.getKey(md5KeyStr);

			// 解密文件
			FileMd5Utils.decrypt(path, purePath + deFilename, key);

			// 解密后文件md5值
			String md5After = FileMd5Utils.getFileMD5String(purePath
					+ deFilename);

			// 写入文件md5文件中
			ps.append(md5After);
			
			// 比较前后的MD5是否一致
			if(md5Origin.equals(md5After)){
				System.out.println("前后MD5值一致,解密成功!");
			}
			
			String name = purePath + deFilename;
			// System.out.println(name);
			// 把文件的旧名称与新名称添加到表格的数据模型
			model.addRow(new String[] { file.getName(), name });

			if (file.exists()) {
				file.delete();
			}

		}
	}
}

工具类:

package com.student.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; 
import java.io.FileOutputStream;  
import java.io.InputStream;  
import java.io.OutputStream;  
import java.security.Key;  
import java.security.SecureRandom;  
  
import javax.crypto.Cipher;  
import javax.crypto.CipherInputStream;  
import javax.crypto.CipherOutputStream;  
import javax.crypto.KeyGenerator; 
 
public class FileMd5Utils {
     protected static char hexDigits[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};  
        protected static MessageDigest messageDigest = null;  
        static{
            try{  
                messageDigest = MessageDigest.getInstance("MD5");  
            }catch (NoSuchAlgorithmException e) {  
                System.err.println(FileMd5Utils.class.getName()+"初始化失败,MessageDigest不支持MD5Util.");  
                e.printStackTrace();  
            }  
        }  
 
        /** 
         * 计算文件的MD5 
         * @param fileName 文件的绝对路径 
         * @return 
         * @throws IOException 
         */ 
        public static String getFileMD5String(String fileName) throws IOException{  
            File f = new File(fileName);  
            return getFileMD5String(f);  
        }  
 
        /** 
         * 计算文件的MD5,重载方法 
         * @param file 文件对象 
         * @return 
         * @throws IOException 
         */ 
        public static String getFileMD5String(File file) throws IOException{  
            FileInputStream in = new FileInputStream(file);  
            FileChannel ch = in.getChannel();  
            MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, file.length());  
            messageDigest.update(byteBuffer);  
            return bufferToHex(messageDigest.digest());  
        }  
 
        private static String bufferToHex(byte bytes[]) {  
           return bufferToHex(bytes, 0, bytes.length);  
        }  
 
        private static String bufferToHex(byte bytes[], int m, int n) {  
           StringBuffer stringbuffer = new StringBuffer(2 * n);  
           int k = m + n;  
           for (int l = m; l < k; l++) {  
            appendHexPair(bytes[l], stringbuffer);  
           }  
           return stringbuffer.toString();  
        }  
 
        private static void appendHexPair(byte bt, StringBuffer stringbuffer) {  
           char c0 = hexDigits[(bt & 0xf0) >> 4];  
           char c1 = hexDigits[bt & 0xf];  
           stringbuffer.append(c0);  
           stringbuffer.append(c1);  
        }  
        public static Key getKey(String strKey){
        	 try {   
        	        KeyGenerator _generator = KeyGenerator.getInstance("DES");   
        	        _generator.init(new SecureRandom(strKey.getBytes()));   
        	        Key key = _generator.generateKey();   
        	        _generator = null;  
        	        return key;
        	    } catch (Exception e) {   
        	        throw new RuntimeException("Error initializing SqlMap class. Cause: " + e);   
        	    }   
        }
        public static void encrypt(String file, String destFile, Key key) throws Exception {   
            Cipher cipher = Cipher.getInstance("DES");   
            // cipher.init(Cipher.ENCRYPT_MODE, getKey());   
            cipher.init(Cipher.ENCRYPT_MODE, key);   
            InputStream is = new FileInputStream(file);   
            OutputStream out = new FileOutputStream(destFile);   
            CipherInputStream cis = new CipherInputStream(is, cipher);   
            byte[] buffer = new byte[1024];   
            int r;   
            while ((r = cis.read(buffer)) > 0) {   
                out.write(buffer, 0, r);   
            }   
            cis.close();   
            is.close();   
            out.close();   
          }   
        
        public static void decrypt(String file, String dest, Key key) throws Exception {   
            Cipher cipher = Cipher.getInstance("DES");   
            cipher.init(Cipher.DECRYPT_MODE, key);   
            InputStream is = new FileInputStream(file);   
            OutputStream out = new FileOutputStream(dest);   
            CipherOutputStream cos = new CipherOutputStream(out, cipher);   
            byte[] buffer = new byte[1024];   
            int r;   
            while ((r = is.read(buffer)) >= 0) {   
                System.out.println();  
                cos.write(buffer, 0, r);   
            }   
            cos.close();   
            out.close();   
            is.close();   
          }   
        
        public static void main(String[] args) throws Exception {  
            String fileName = "G:/key.png";
            String md5KeyStr = getFileMD5String(fileName);
            Key key = getKey(md5KeyStr);
            String md5Origin = getFileMD5String("G:/myworks/winter.doc");
            encrypt("G:/myworks/winter.doc","G:/myworks/winterEncrypt.doc",key);
            decrypt("G:/myworks/winterEncrypt.doc","G:/myworks/winterDec.doc",key);
            String md5After = getFileMD5String("G:/myworks/winterDec.doc");
            System.out.println(md5Origin.equals(md5After));
            
        }  
}



  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值