这是我参与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();
}