标签:
MD5,英文意思是Message Digest,即信息摘要,是常用的信息摘要算法。
它是一种不可逆的算法,也就是说,假如将一个信息MD5摘要成一串代码,将不能通过这串代码还原回原来的信息。
出于这种特性,MD5常用来校验密码是否正确、校验下载文件是否完整无损。
> 校验密码是否正确:将用户注册的密码MD5摘要后储存起来,待用户登录时将用户录入的密码MD5摘要,对比两次摘要后的信息是否相等,相等即密码正确。(这里如果加盐会更好,见后面章节)
> 校验下载文件是否完整无损:我们常下载开源文件资源包时,可以看到网站上提供的该资源包的MD5(比如下载POI,如图一),下载文件完毕后,可通过自己的程序或直接去一些网站上计算其MD5码,如果与官网上提供的一致,则表示文件完整无损。(图二第3行日志可见,以下程序计算的MD5码与图一的官网截图一致)
如上图一可见,123456的MD5码为e10adc3949ba59abbe56e057f20f883e。
如果你的系统用MD5摘要,并且无加盐,还经常使用123456为测试密码,对这一串MD5码一定很熟悉。这一些MD5码就静静地躺在DB中待校验。
如果数据库被暴露(比如拖库),坏人得到了这些MD5码,就可以通过常用密码与其MD5码的映射关系,轻而易举地翻译出大多数密码。
所以,一般来说,我们需要对原始密码进行加盐,所谓加盐,就是按照一定规则扰乱原有字符串,然后再进行MD5摘要。这个规则,自己定义,并且一定保密。
目前Spring应用广泛,我们就直接使用Spring的api获取MD5码了。
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()); } }
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(); } }
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); } }
图一
图二
标签:
原文地址:http://www.cnblogs.com/nick-huang/p/5067764.html