MD5为什么不可逆

1,397 阅读2分钟

这是我参与8月更文挑战的第18天,活动详情查看:8月更文挑战

MD5为什么不可逆

很早就用过MD5,文件对比,字符串加密,也很早的就听说MD5是不可逆的算法,那么MD5为什么不可逆呢。

一、了解MD5

MD5全称MD5信息摘要算法(英语:MD5 Message-Digest Algorithm)可以产出128位的散列值,用于确保信息传输完整一致。

2004年,证实MD5算法无法防止碰撞,因此不适用于安全性认证,如SSL公开密钥认证或是数字签名等用途。

即时如此,在应用中依然有大量的应用在使用,比如文件的MD5对比,手机号码转MD5的脱敏处理等等。

二、MD5为什么不可逆

MD5不可逆的原因是其是一种散列函数,使用的是hash算法,在计算过程中原文的部分信息是丢失了的。

hash是什么意思呢? Hash,一般翻译做“散列”,也有直接音译为“哈希”
就是把任意长度的输入通过散列算法,变换成固定长度的输入,相当于一种压缩映射,将任意长度的消息压缩到某一固定长度的消息摘要的函数。

信息丢失是什么意思呢? 比如说一个超过short范围的int,强转成了short,再想转为int能还原吗,显然是不能的。

再比如我有一个值为

01001111

然后左移两位得到

00111100

然后再怎么还原呢,右移两位可不能还原了。

三、MD5为什么可以碰撞破解

我们希望

如果 key1 ≠ key2,那 hash(key1) ≠ hash(key2)

明确一个观念

MD5生成的值排列是有限的,而字符串组合的排列是无限的

有一个原理,叫抽屉原理。

桌上有十个苹果,要把这十个苹果放到九个抽屉里,无论怎样放,我们会发现至少会有一个抽屉里面至少放两个苹果。这一现象就是我们所说的“抽屉原理”。

那么就可能出现 hash(key1) == hash(key2)的情况,所以就有可能进行碰撞破解。

无论设置的存储区域(n)有多大,当需要存储的数据大于 n 时,那么必然会存在哈希值相同的情况。这就是所谓的散列冲突

四、JAVA 中使用MD5

 /**
     * Java中的md5
     * @param content 输入的值
     * @return 输出md5加密后的值
     */
    public static String md5Java(String content) {
        byte[] hash;
        try {
            hash = MessageDigest.getInstance("MD5").digest(content.getBytes());
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("NoSuchAlgorithmException", e);
        }

        StringBuilder hex = new StringBuilder(hash.length * 2);
        for (byte b : hash) {
            if ((b & 0xFF) < 0x10) {
                hex.append(0);
            }
            hex.append(Integer.toHexString(b & 0xff));
        }

        return hex.toString();
    }