Java实现批量文件加密

来源:互联网 发布:整篇文章翻译软件 编辑:程序博客网 时间:2024/05/02 00:14

一、题目要求:

用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;// 保存文件扩展名}@Overridepublic 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 blocke1.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 blocke1.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 0