从网络安全性到MD5文件加密算法和工具开发

1.最近来自半岛的网络木马病毒横行,人心惶惶。安全威胁应该从源头把关,不要下载安装来源不明的软件,软件开发者提供软件的同时,要在官网公布软件的MD5校验,以供用户分辨真假李逵,既能防止开发者辛苦研发出来的软件成为黑帽子们挂马的载体,也能防止唯利是图的广告商插播广告,侵害开发者利益。MD5加密是一种广范用于安全加秘和文件防篡改的加密算法。可以为文件,字串提供完整型保护。


2.MD5计算步骤   

MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。

第一步、填充

     如果输入信息的长度(bit)对512求余的结果不等于448,就需要填充使得对512求余的结果等于448。填充的方法是填充一个1和n个0。填充完后,信息的长度就为N*512+448(bit);MD5计算步骤   

MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。

第一步、填充

     如果输入信息的长度(bit)对512求余的结果不等于448,就需要填充使得对512求余的结果等于448。填充的方法是填充一个1和n个0。填充完后,信息的长度就为N*512+448(bit);

第二步、记录信息长度

     用64位来存储填充前信息长度。这64位加在第一步结果的后面,这样信息长度就变为N*512+448+64=(N+1)*512位。

第三步、装入标准的幻数(四个整数)

     标准的幻数(物理顺序)是(A=(01234567)16,B=(89ABCDEF)16,C=(FEDCBA98)16,D=(76543210)16)。如果在程序中定义应该是(A=0X67452301L,B=0XEFCDAB89L,C=0X98BADCFEL,D=0X10325476L)。有点晕哈,其实想一想就明白了。

第四步、四轮循环运算


3 。开发工具软件,用于给软件和文件夹提供MD5校验




package com.mysiming.util;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.HeadlessException;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.security.MessageDigest;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

public class frame extends JFrame {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1926273287648990244L;
	private JPanel contentPane;

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

	/**
	 * Create the frame.
	 */
	int win_X = 100, win_Y = 100, win_W = 600, win_H = 400;
	int title_W = 154, title_H = 15, title_X = win_W / 2 - title_W / 2, title_Y = 20;

	int buttonX = 80, buttonY = 80 + 20, buttonW = 80, buttonH = 30, buttonSPACE = 20;
	int file_X = 100, file_Y = 20 + 20, file_W = 400, file_H = 21;
	int fileL_X = 20, fileL_Y = 26 + 20, fileL_W = 84, fileL_H = 15;
	int md5_X = 100, md5_Y = 50 + 20, md5_W = 400, md5_H = 21;
	int md5L_X = 20, md5L_Y = 56 + 20, md5L_W = 84, md5L_H = 15;

	int buttonY2 = 80 + 20 + 220;
	int file_Y2 = 20 + 20 + 130;
	int fileL_Y2 = 26 + 20 + 130;
	int md5_Y2 = 50 + 20 + 130;
	int md5L_Y2 = 56 + 20 + 130;
	int md5_H2 = 100;

	int title_Y2 = 20 + 130;
	String Logpath;

	public frame() {
		setBackground(Color.PINK);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(win_X, win_Y, win_W, win_H);
		contentPane = new JPanel();
		contentPane.setBackground(Color.GRAY);
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new BorderLayout(0, 0));
		setContentPane(contentPane);

		JLayeredPane layeredPane = new JLayeredPane();
		layeredPane.setBackground(Color.CYAN);
		contentPane.add(layeredPane, BorderLayout.CENTER);

		JTextField textField = new JTextField();
		textField.setBounds(file_X, file_Y, file_W, file_H);
		layeredPane.add(textField);
		textField.setColumns(10);

		JTextField textField_1 = new JTextField();
		textField_1.setBounds(md5_X, md5_Y, md5_W, md5_H);
		layeredPane.add(textField_1);
		textField_1.setColumns(10);

		JLabel lblSetFile = new JLabel("设置文件");
		lblSetFile.setBounds(fileL_X, fileL_Y, fileL_W, fileL_H);
		layeredPane.add(lblSetFile);

		JLabel lblMd5 = new JLabel("设置Md5");
		lblMd5.setBounds(md5L_X, md5L_Y, md5L_W, md5L_H);
		layeredPane.add(lblMd5);

		/**
		 * JFileChooser 是Java Swing提供的文件选择对话框
		 */

		JFileChooser jfc = new JFileChooser();// 构造一个指向用户默认目录的 JFileChooser。
		Button btnSet = new Button("选择文件");// Browse按钮用于获取文件
		btnSet.addActionListener(new ActionListener() {// Browse按钮 的 监听事件
			public void actionPerformed(ActionEvent arg0) {
				int result = jfc.showOpenDialog(null);// 弹出一个 "Open File"
														// 文件选择器对话框。
				String filepath = ""; // 初始化变量filepath(文件路径)
				if (result == JFileChooser.APPROVE_OPTION) {// JFileChooser.APPROVE_OPTION是个整型
					// 常量,代表0,当返回0值时,执行相关操作。
					filepath = jfc.getSelectedFile().getAbsolutePath();// 获得你选择的文件的绝对路径
					textField.setText(filepath);// 将选择的文件的绝对路径在文本框textField中显示。
				}

				String ff = textField.getText();
				int backslashIndex = ff.lastIndexOf('\\');
				// 路径名是最后一个'/'之前的字符
				Logpath = ff.substring(0, backslashIndex + 1);
				System.out.println(Logpath);
			}
		});
		btnSet.setBounds(buttonX, buttonY, buttonW, buttonH);
		layeredPane.add(btnSet);

		Button btnMd = new Button("生成MD5");// ********Count
											// Md5用于计算MD5值***********
		btnMd.addActionListener(new ActionListener() {// Count Md5按钮的监听事件
			public void actionPerformed(ActionEvent e) {
				File file = jfc.getSelectedFile();// 返回选中的文件
				String filemd5 = getMd5ByFile(file);// 得到文件的MD5值
				textField_1.setText(filemd5);// 将文件的MD5值在文本框textField中显示出来。
			}
		});
		btnMd.setBounds(buttonX + buttonW + buttonSPACE, buttonY, buttonW, buttonH);
		layeredPane.add(btnMd);

		Button checkMd = new Button("校验MD5");// ********Count
												// Md5用于计算MD5值***********
		checkMd.addActionListener(new ActionListener() {// Count Md5按钮的监听事件
			public void actionPerformed(ActionEvent e) {
				File file = jfc.getSelectedFile();// 返回选中的文件
				String filemd5 = getMd5ByFile(file);// 得到文件的MD5值
				String checkMd5 = textField_1.getText();
				Toolkit.getDefaultToolkit().beep();
				if (filemd5.equals(checkMd5)) {
					JOptionPane.showMessageDialog(null, "MD5校验正确", "MD5校验正确", JOptionPane.INFORMATION_MESSAGE);
				} else {
					JOptionPane.showMessageDialog(null, "MD5校验不对", "MD5校验不对", JOptionPane.INFORMATION_MESSAGE);
				}
			}
		});
		checkMd.setBounds(buttonX + buttonW * 2 + buttonSPACE * 2, buttonY, buttonW, buttonH);
		layeredPane.add(checkMd);

		Button saveMd = new Button("保存MD5");// ********Count
											// Md5用于计算MD5值***********
		saveMd.addActionListener(new ActionListener() {// Count Md5按钮的监听事件
			public void actionPerformed(ActionEvent e) {
				File file = jfc.getSelectedFile();// 返回选中的文件
				String filemd5 = getMd5ByFile(file);// 得到文件的MD5值
				String checkMd5 = textField_1.getText();
				String str = file.getPath() + "|" + filemd5;
				writeCheckSum(Logpath + "md5checksum.txt", str);
			}
		});
		saveMd.setBounds(buttonX + buttonW * 3 + buttonSPACE * 3, buttonY, buttonW, buttonH);
		layeredPane.add(saveMd);

		JLabel title = new JLabel("文件MD5");
		title.setBounds(title_X, title_Y, title_W, title_H);
		layeredPane.add(title);
		// ****************************************************************************************//\
		JTextField textField2 = new JTextField();
		textField2.setAutoscrolls(true);
		textField2.setBounds(file_X, file_Y2, file_W, file_H);
		layeredPane.add(textField2);
		textField2.setColumns(10);

		JTextArea textField_12 = new JTextArea();
		JScrollPane scroll = new JScrollPane(textField_12);
		scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
		scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		// textField_12.setAutoscrolls(true);
		// textField_12.setLineWrap(true);
		scroll.setBounds(md5_X, md5_Y2, md5_W, md5_H2);
		// textField_12.setBounds(md5_X, md5_Y2, md5_W, md5_H2);
		// layeredPane.add(textField_12);
		layeredPane.add(scroll);
		// textField_12.setColumns(10);

		JLabel lblSetFile2 = new JLabel("设置文件夹");
		lblSetFile2.setBounds(fileL_X, fileL_Y2, fileL_W, fileL_H);
		layeredPane.add(lblSetFile2);

		JLabel lblMd52 = new JLabel("设置Md5路径");
		lblMd52.setBounds(md5L_X, md5L_Y2, md5L_W, md5L_H);
		layeredPane.add(lblMd52);

		/**
		 * JFileChooser 是Java Swing提供的文件选择对话框
		 */
		JFileChooser jfc2 = new JFileChooser();// 构造一个指向用户默认目录的 JFileChooser。
		Button btnSet2 = new Button("选择文件夹");// Browse按钮用于获取文件
		btnSet2.addActionListener(new ActionListener() {// Browse按钮 的 监听事件
			public void actionPerformed(ActionEvent arg0) {

				jfc2.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);// 只能选择目录
				String path = null;
				File f = null;
				int flag = 0;
				try {
					flag = jfc2.showOpenDialog(null);
				} catch (HeadlessException head) {
					System.out.println("Open File Dialog ERROR!");
				}
				if (flag == JFileChooser.APPROVE_OPTION) {
					// 获得该文件
					f = jfc2.getSelectedFile();
					path = f.getPath();
					textField2.setText(path);// 将选择的文件的绝对路径在文本框textField中显示。
				}
			}
		});
		btnSet2.setBounds(buttonX, buttonY2, buttonW, buttonH);
		layeredPane.add(btnSet2);

		Button btnMd2 = new Button("生成MD5");// ********Count
											// Md5用于计算MD5值***********
		btnMd2.addActionListener(new ActionListener() {// Count Md5按钮的监听事件
			public void actionPerformed(ActionEvent e) {
				textField_12.setText("");
				File file = new File(textField2.getText());
				File[] tempList = file.listFiles();
				System.out.println("该目录下对象个数:" + tempList.length);
				StringBuffer sb = new StringBuffer();
				for (int i = 0; i < tempList.length; i++) {
					if (tempList[i].isFile()) {
						if (tempList[i].getName().indexOf("md5checksum") != 0) {
							System.out.println("文     件:" + tempList[i]);
							String filemd5 = getMd5ByFile(tempList[i]);// 得到文件的MD5值
							// textField_12.setText(sb.toString());//将文件的MD5值在文本框textField中显示出来。\
							textField_12.append(tempList[i].getName() + "|" + filemd5 + "\r\n");
						}
					}
				}
			}
		});
		btnMd2.setBounds(buttonX + buttonW + buttonSPACE, buttonY2, buttonW, buttonH);
		layeredPane.add(btnMd2);

		Button checkMd2 = new Button("校验MD5");// ********Count
												// Md5用于计算MD5值***********
		checkMd2.addActionListener(new ActionListener() {// Count Md5按钮的监听事件
			public void actionPerformed(ActionEvent e) {

				boolean error = false;
				String tempstr;
				File file = new File(textField2.getText() + "\\" + "md5checksum.txt");
				if (!file.exists()) {
					JOptionPane.showMessageDialog(null, "MD5校验不对", "找不到md5checksum.txt",
							JOptionPane.INFORMATION_MESSAGE);
				}

				try {
					FileInputStream fis;
					fis = new FileInputStream(file);
					BufferedReader br = new BufferedReader(new InputStreamReader(fis));
					while ((tempstr = br.readLine()) != null) {
						System.out.println(">>>>>>>>>>>>>>>" + tempstr);
						if (tempstr.indexOf('|') != -1) {
							String[] s = tempstr.split("\\|");
							System.out.println(">>>>>>>>>>>>>>>" + s[0]);
							System.out.println(">>>>>>>>>>>>>>>" + s[1]);
							System.out.println(">>>>>>>>>>>>>>>" + textField2.getText() + "\\" + s[0]);
							File f = new File(textField2.getText() + "\\" + s[0]);
							System.out.println(">>>>>>>>>>>>>>>" + f.getPath());
							String filemd5 = getMd5ByFile(f);// 得到文件的MD5值
							System.out.println(">>>>>>>>>>>>>>>filemd5=" + filemd5);
							if (!filemd5.equals(s[1])) {
								JOptionPane.showMessageDialog(null, textField2.getText() + "\\" + s[0] + "校验不对",
										"MD5校验不对", JOptionPane.INFORMATION_MESSAGE);
								error = true;
								break;
							}
						}
					}
					if (!error) {
						JOptionPane.showMessageDialog(null, "MD5校验成功", "校验成功", JOptionPane.INFORMATION_MESSAGE);
					}
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}

			}
		});
		checkMd2.setBounds(buttonX + buttonW * 2 + buttonSPACE * 2, buttonY2, buttonW, buttonH);
		layeredPane.add(checkMd2);

		Button saveMd2 = new Button("保存MD5");// ********Count
												// Md5用于计算MD5值***********
		saveMd2.addActionListener(new ActionListener() {// Count Md5按钮的监听事件
			public void actionPerformed(ActionEvent e) {

				String str = textField_12.getText();
				writeCheckSum(textField2.getText() + "\\" + "md5checksum.txt", str);
			}
		});
		saveMd2.setBounds(buttonX + buttonW * 3 + buttonSPACE * 3, buttonY2, buttonW, buttonH);
		layeredPane.add(saveMd2);

		JLabel title2 = new JLabel("文件夹MD5");
		title2.setBounds(title_X, title_Y2, title_W, title_H);
		layeredPane.add(title2);
	}

	public static void getFileList(String path) {
		File file = new File(path);
		File[] tempList = file.listFiles();
		System.out.println("该目录下对象个数:" + tempList.length);
		for (int i = 0; i < tempList.length; i++) {
			if (tempList[i].isFile()) {
				System.out.println("文     件:" + tempList[i]);
			}
		}
	}

	public static void writeCheckSum(String path, String str) {
		try {
			// String path="/root/test/testfilelog.log";
			File file = new File(path);
			if (!file.exists())
				file.createNewFile();
			// SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			FileOutputStream out = new FileOutputStream(file, false); // 如果追加方式用true
			StringBuffer sb = new StringBuffer();
			// sb.append("-----------"+sdf.format(new Date())+"------------\n");
			sb.append(str + "\n");
			out.write(sb.toString().getBytes("utf-8"));// 注意需要转换对应的字符集
			out.close();
		} catch (IOException ex) {
			System.out.println(ex.getStackTrace());
		}
	}

	public static String getMd5ByFile(File file) {
		String value = null;
		FileInputStream in = null;
		try {
			in = new FileInputStream(file);
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		}
		try {
			MessageDigest md5 = MessageDigest.getInstance("MD5");

			byte[] buffer = new byte[8192];
			int length;
			while ((length = in.read(buffer)) != -1) {
				md5.update(buffer, 0, length);
			}

			BigInteger bi = new BigInteger(1, md5.digest());
			value = bi.toString(16);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (null != in) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return value;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值