MD5介绍、使用场景和使用中的注意事项

来源:互联网 发布:genbank数据库 编辑:程序博客网 时间:2024/06/06 13:03

序言

MD5作为一种常见常用的加密算法,在项目中也是多次使用了,常见的不一定注意的到。昨天老大问我,我们项目的MD5加密怎么做的,明文还是密文传输,有没有设置偏移量,一下子竟然没反应过来怎么回事儿=,=还是整理一下吧。

MD5介绍

MD5算法是广泛使用的杂凑函数,也就是哈希函数,英文全拼是:Message Digest Algorithm,对应的中文名字是消息摘要算法,这都不重要,重要的是了解这种算法有什么特点应该怎么使用。
- 一个任意长度的数据,经过MD5计算后就会得到一个长度固定的十六进制字符串;
- MD5算法消耗较低,不会在性能在造成压力;
- 抗修改性很强,相差极小的两个原数据的MD5值差异会很大
- 抗碰撞性也很强,伪造数据的难度很大

这里解释一下抗碰撞性。抗碰撞性是相对与碰撞攻击讲,碰撞攻击指两个不同的原数据在算法加密后得到了相同的值。MD5具有很强的抗碰撞性(此处看了不少资料,好像王小云教授的算法已经能够破解MD5的防碰撞性)。

MD5常见的用途

MD5常常作为文件的签名出现,我们在下载文件的时候,常常会看到文件页面上附带一个扩展名为.MD5的文本或者一行字符,这行字符就是就是把整个文件当作原数据通过MD5计算后的值,我们下载文件后,可以用检查文件MD5信息的软件对下载到的文件在进行一次计算。两次结果对比就可以确保下载到文件的准确性。
另一种常见用途就是网站敏感信息加密,比如用户名密码,支付签名等等。随着https技术的普及,现在的网站广泛采用前台明文传输到后台,MD5加密(使用偏移量)的方式保护敏感数据保护站点和数据安全。

使用MD5加密

主流的编程语言基本上都已经有封装好的MD5加密算法可以使用,这边来介绍一下java如何使用语言自带的包完成MD5加密算法。

package util;import org.apache.commons.codec.EncoderException;import java.security.MessageDigest;/** * Created by Vivi on 2017/5/12. */public class EncodeUtil {    //MD5加密    public String MD5Util(String data) {        //获得java提供信息摘要算法加密功能类的一个实例        MessageDigest md5 = null;        try {            md5 = MessageDigest.getInstance("MD5");        } catch (Exception e) {            System.out.println(e.toString());            e.printStackTrace();        }        //将获取到的string转换成byte数组        char[] chars = data.toCharArray();        byte[] bytes = new byte[chars.length];        for (int i = 0; i < chars.length; i++) {            bytes[i] = (byte) chars[i];        }        //获取MD5计算后的byte值        byte[] md5byte = md5.digest(bytes);        //将获取到的byte值转回string        StringBuffer stringBuffer = new StringBuffer();        for (int i = 0; i < md5byte.length; i++) {        //使用0xff保持转值不出错            int val = ((int) md5byte[i]) & 0xff;            if (val < 16) {                stringBuffer.append("0");            } else {                stringBuffer.append(Integer.toHexString(val));            }        }        return stringBuffer.toString();    }    // 测试主函数    public static void main(String args[]) {        EncodeUtil util = new EncodeUtil();        String s = new String("123456");        System.out.println("原始:" + s);        System.out.println("MD5后:" + util.MD5Util(s));    }}

注意事项

抛去MD5的安全性不讲,由于MD5算法是公开的,所有人都可以获得和使用MD5算法,如果不对MD5算法进行一些处理,那么当我们将自己的重要接口暴露在互联网上的时候,比如登陆接口,攻击者就可以同样利用MD5加密算法对我们进行撞库攻击和关键信息比对。我们应当如何处理这种情况呢?
首先肯定是整个应用程序的流控,限制单个IP、单个用户、非法IP的不正常访问,这些能够很大程度上避免攻击者不受限制的调用我们的接口撞库攻击。
Tips:流控是一个成熟系统必备的模块,它的功能作用不止于此,这里就不过多讨论了。
其次就是对MD5算法偏移了。由于MD5算法是公开的,那就意味着别人可以利用相同的算法针对你的加密值不断地进行计算。为了避免这个问题,我们可以给算法增加一个偏移量,比如在原始数据上拼接一段数据在进行加密;或者根据原始数据分布范围进行转换,用得到的新值进行MD5计算,这样子被破解的风险就会大大降低。