MD5 加密算法详解

MD5的概念

       MD5算法是单向散列算法的一种。单向散列算法也称为HASH算法,是一种将任意长度的信息压缩至某一固定长度(称之为消息摘要)的函数(该压缩过程不可逆)。在MD5算法中,这个摘要是指将任意数据映射成一个128位长的摘要信息。并且其是不可逆的,即从摘要信息无法反向推演中原文。MD5算法最终生成的是一个128位长的数据,从原理上说,有2^128种可能,这是一个非常巨大的数据,约等于3.4乘10的38次方,虽然这个是个天文数字,但是世界上可以进行加密的数据原则上说是无限的,因此是可能存在不同的内容经过MD5加密后得到同样的摘要信息,但这个碰中的概率非常小。可用于数字签名、信息完整性检查等用途;

注意:md5值不是唯一的,也就是一个原始数据,只对应一个md5值,但是一个md5值,可能对应多个原始数据。且md5值是可以被破解的,例撞库破解

MD5的特点

  • 无论输入的消息有多长,加密后的长度总是固定的。
  • 一般地,只要输入的消息不同,对其进行加密后产生的内容也必不相同;但相同的输入必会产生相同的输出。
  • 只能进行正向的信息加密,而无法从加密内容中恢复出任何的原消息,甚至根本就找不到任何与原信息相关的信息(不可逆性)。
     

MD5的作用

  • 一致性检验,如大文件上传时,需要对文件一致性校验;
  • 数字签名,还是最上面那个例子。只是把md5看出了一个指纹,按了个手印说明独一无二了。
  • 安全访问认证

如:在用户注册时,会将密码进行md5加密,存到数据库中。这样可以防止那些可以看到数据库数据的人,恶意操作了。

java实现md5加密

1、加密字符串普通不加盐

/**
	 * 加密字符串普通不加盐
	 * @param text
	 */
	public static String msgMD5(String text) {
		try {
			//1、生成一个MD5加密计算摘要
			MessageDigest instance = MessageDigest.getInstance("MD5");
			//2 、将消息变成byte数组
			byte[] bytes = text.getBytes();
			//3 、计算MD5加密后的16字节(128位)摘要
			byte[] buff = instance.digest(bytes);
			//4 把字节数组转换成16进制字符串
			String key = bytesToHex(buff);
			return key;
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "";
	}

/**
     * 	将指定byte数组转换成16进制字符串
     * @param bytes
     * @return
     */
    public static String bytesToHex(byte[] bytes) {
        StringBuffer md5str = new StringBuffer();
        //把数组每一字节换成16进制连成md5字符串
        int digital;
        for (int i = 0; i < bytes.length; i++) {
             digital = bytes[i];
 
            if(digital < 0) {
                digital += 256;
            }
            if(digital < 16){
                md5str.append("0");
            }
            md5str.append(Integer.toHexString(digital));
        }
        return md5str.toString().toUpperCase();
    }
    
    
    /**
     *	 将16进制字符串转换成字节数组
     * @param hex
     * @return
     */
    public static byte[] String16ToBytes(String str) {
		if (str == null) {
	        return null;
	    }
	    if (str.length() == 0) {
	        return new byte[0];
	    }
	    byte[] byteArray = new byte[str.length() / 2];
	    for (int i = 0; i < byteArray.length; i++){
	        String subStr = str.substring(2 * i, 2 * i + 2);
	        byteArray[i] = ((byte)Integer.parseInt(subStr, 16));
	    }
	    return byteArray;
	}

2、 加密字符串普通加盐

/**
	 * 加密字符串普通加盐
	 * @param password 待加密数据
	 * @param salt 盐
	 * @return
	 */
	public static String textEncryptMD5(String password,String salt) {
 		MessageDigest md5 = null;
		try {
			md5 = MessageDigest.getInstance("MD5");
			md5.update(salt.getBytes());
			byte[] bs = md5.digest(password.getBytes());
			StringBuffer hexValue = new StringBuffer();
			//循环将字节数组转换成16进制字符串
			for (int i = 0; i < bs.length; i++) {
				int val = ((int) bs[i]) & 0xff;
				if (val < 16)
					hexValue.append("0");
				hexValue.append(Integer.toHexString(val));
			}
			return hexValue.toString();
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "";
	}

3、加密文件

/**
	 * 加密文件,不加密
	 * 1.获取文件的读取流
	 * 2.不停的读取流中的"内容"放入字符串,放一部分就"更新"一部分.直到全部完毕
	 * 3.然后调用md5.digest();就会得到有内容的字节数组了.
	 * @param file
	 * @return
	 * @throws Exception
	 */
	public static String fileEncryptMD5(File file) throws Exception {
            String MD5 = "";
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            FileInputStream fis = new FileInputStream(file);
            byte[] bytes = new byte[1024 * 5];
            int len = -1;
            while ((len=fis.read(bytes))!=-1) {
                md5.update(bytes, 0, len);
            }
            fis.close();
            byte[] digest = md5.digest();
            for (int i = 0; i <digest.length; i++) {
                int n = digest[i] & 0x000000ff;
                String s = Integer.toHexString(n);
                MD5 += s;
            }
            return MD5;
	 }

 

 

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值