任何消息经过散列函数处理后,都会产生一个唯一的散列值,这个散列值可以用来验证消息的完整性。计算消息散列值的过程被称为“消息摘要”,计算消息散列值的算法被称为消息摘要算法。常使用的消息摘要算法有:MD—消息摘要算法,SHA—安全散列算法,MAC—消息认证码算法。本文主要来了解MD算法。
MD5算法是典型的消息摘要算法,它是由MD4,MD3和MD2算法演变而来。无论是哪一种MD算法,其原理都是接受一个任意长度的消息并产生一个128位的消息摘要。如果把得到的消息摘要转换成十六进制字符串,则会得到一个32字节长度的字符串,我们平常见到的大部分MD数字指纹就是一个长度为32的十六进制字符串。
假设原始消息长度是b(以bit为单位),注意这里b可以是任意长度,并不一定要是8的整数倍。计算该消息MD5值的过程如下:
在计算消息的MD5值之前,首先对原始信息进行填充,这里的信息填充分为两步。
第一步,对原始信息进行填充,填充之后,要求信息的长度对512取余等于448。填充的规则如下:假设原始信息长度为b bit,那么在信息的b+1 bit位填充1,剩余的位填充0,直到信息长度对512取余为448。这里有一点需要注意,如果原始信息长度对512取余正好等于448,这种情况仍然要进行填充,很明显,在这时我们要填充的信息长度是512位,直到信息长度对512取余再次等于448。所以,填充的位数最少为1,最大为512。
第二步,填充信息长度,我们需要把原始信息长度转换成以bit为单位,然后在第一步操作的结果后面填充64bit的数据表示原始信息长度。第一步对原始信息进行填充之后,信息长度对512取余结果为448,这里再填充64bit的长度信息,整个信息恰好可以被512整除。其实从后续过程可以看到,计算MD5时,是将信息分为若干个分组进行处理的,每个信息分组的长度是512bit。
在进行MD5值计算之前,我们先来做一些定义。
下面就是最核心的信息处理过程,计算MD5的过程实际上就是轮流处理每个信息分组的过程。
MD5算法实现如下所示。
这里也和Java提供的标准MD5算法进行了对比,通过测试可以看到该MD5计算的结果和Java标准MD5算法的计算结果是一样的。
这是我以前做的一个小项目时用到md5写的
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
//将用户密码进行md5加密 并返回加密后的32位十六进制密码
public class MD5Util {
public static String md5(String password) {
try {
// 获取md5对象
MessageDigest md = MessageDigest.getInstance("md5")
// 获取加密后的密码并返回十进制字节数组
byte[] bytes = md.digest(password.getBytes())
// 遍历数组得到每个十进制数并转换成十六进制
StringBuffer sb = new StringBuffer()
for (byte b : bytes) {
// 把每个数转成十六进制 存进字符中
sb.append(toHex(b))
}
String finish = sb.toString()
return finish
} catch (NoSuchAlgorithmException e) {
e.printStackTrace()
throw new RuntimeException(e)
}
}
// 十进制转十六进制方法
private static String toHex(byte b) {
int target = 0
if (b <0) {
target = 255 + b
} else {
target = b
}
int first = target / 16
int second = target % 16
return Hex[first] + Hex[second]
}
static String[] Hex = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"a", "b", "c", "d", "e", "f" }
/*public static void main(String[] args) {
String a = MD5Util.md5("1234")
System.out.println(a)
}*/
}