【Java】聊聊常用的MD5的使用

MD,全文是Message Digest,即信息摘要的意思,是常用的信息摘要算法。

它是一种不可逆的算法,也就是说,假如将一个信息MD5摘要成一串代码,将不能通过这串代码还原回原来的信息。

 

> 使用的场景

出于这种特性,MD5常用来校验密码是否正确、校验下载文件是否完整无损。

-> 校验密码是否正确:将用户注册的密码MD5摘要后储存起来,待用户登录时将用户录入的密码MD5摘要,对比两次摘要后的信息是否相等,相等即密码正确。(这里如果加盐会更好,见后面章节)

-> 校验下载文件是否完整无损:我们常下载开源文件资源包时,可以看到网站上提供的该资源包的MD5(比如下载POI,如图一),下载文件完毕后,可通过自己的程序或直接去一些网站上计算其MD5码,如果与官网上提供的一致,则表示文件完整无损。(图二第3行日志可见,以下程序计算的MD5码与图一的官网截图一致)

 

> 直接进行MD5是否足够

如上图一可见,123456的MD5码为e10adc3949ba59abbe56e057f20f883e。

如果你的系统用MD5摘要,并且无加盐,还经常使用123456为测试密码,对这一串MD5码一定很熟悉。这一些MD5码就静静地躺在DB中待校验。

如果数据库被暴露(比如拖库),坏人得到了这些MD5码,就可以通过常用密码与其MD5码的映射关系,轻而易举地翻译出大多数密码。

 

所以,一般来说,我们需要对原始密码进行加盐,所谓加盐,就是按照一定规则扰乱原有字符串,然后再进行MD5摘要。这个规则,自己定义,并且一定保密。

 

> 调用Spring工具类获取MD5码

目前Spring应用广泛,我们就直接使用Spring的api获取MD5码了。

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>3.2.15.RELEASE</version>
</dependency>
View Code

 

package com.nicchagil.md5study;

import org.springframework.util.DigestUtils;

public class MD5UtilBySpring {
    
    /**
     * 使用MD5作信息摘要,并以十六进制表示
     */
    public static String md5(byte[] bytes) {
        return DigestUtils.md5DigestAsHex(bytes);
    }

    /**
     * 使用MD5作信息摘要,并以十六进制表示
     */
    public static String md5(String s) {
        if (s == null || s.length() == 0) {
            return null;
        }
        return MD5UtilBySpring.md5(s.getBytes());
    }
    
}
View Code

 

package com.nicchagil.md5study;

public class Salter {
    
    public static final String PREFIX = "HOW";
    public static final String FILLING = "ARE";
    public static final Integer FILLING_INDEX = 5;
    public static final String POSTFIX = "YOU!";
    
    public static String salt(String source) {
        if (source == null || source.length() == 0) {
            return null;
        }
        
        StringBuffer sb = new StringBuffer(source);
        if (sb.length() > FILLING_INDEX) {
            sb.insert(FILLING_INDEX, FILLING);
        }
        
        return sb.insert(0, PREFIX).append(POSTFIX).toString();
    }

}
View Code

 

package com.nicchagil.md5study;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;

import org.junit.Test;

public class HowToUse {
    
    @Test
    public void test() throws Exception {
        String source = "123456";
        String md5Hex = MD5UtilBySpring.md5(source);
        System.out.println(source + "'s hex md5 -> " + md5Hex);
    }
    
    @Test
    public void test2() throws Exception {
        File file = new File("d:/poi-bin-3.13-20150929.tar.gz");
        
        FileInputStream fis = null;
        ByteArrayOutputStream baos = null;
        try {
            fis = new FileInputStream(file);
            baos = new ByteArrayOutputStream();
            
            byte[] bytes = new byte[1024];
            int size = 0;
            while ((size = fis.read(bytes)) != -1) {
                if (size == 1024) {
                    baos.write(bytes);
                } else {
                    baos.write(bytes, 0, size);
                }
            }
            
            byte[] resultBytes = baos.toByteArray();
            System.out.println("size -> " + resultBytes.length);
            String md5Hex = MD5UtilBySpring.md5(resultBytes);
            System.out.println("Hex md5 -> " + md5Hex);
        } finally {
            if (fis != null) {
                fis.close();
            }
            if (baos != null) {
                baos.close();
            }
        }
    }
    
    @Test
    public void test3() throws Exception {
        String source = "123456";
        String saltSource = Salter.salt(source);
        String md5 = MD5UtilBySpring.md5(saltSource);
        System.out.println(source + " salt -> " + saltSource + " MD5 -> " + md5);
        
        source = "12345";
        saltSource = Salter.salt(source);
        md5 = MD5UtilBySpring.md5(saltSource);
        System.out.println(source + " salt -> " + saltSource + " MD5 -> " + md5);
        
        source = "1234";
        saltSource = Salter.salt(source);
        md5 = MD5UtilBySpring.md5(saltSource);
        System.out.println(source + " salt -> " + saltSource + " MD5 -> " + md5);
    }
    
}
View Code

 

图一

 

图二

 

> 拓展

类似功能的算法还有SHA(Secure Hash Algorithm)

 

你可能感兴趣的:(【Java】聊聊常用的MD5的使用)