MD5与SHA-1简介
MD5简介
MD5
即Message-Digest Algorithm 5
(信息-摘要算法5), 用于确保信息传输完整一致. 是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法), 将数据运算为另一固定长度值,是杂凑算法的基础原理,主流编程语言普遍已有MD5实现。MD5
的前身有MD2
、MD3
和MD4
。
MD5算法的特点
- 压缩性: 任意长度的数据,算出的MD5值的长度都是固定的
- 容易计算: 从原数据计算出MD5值很容易
- 抗修改性: 对原数据进行任何改动,修改一个字节生成的MD5值区别也会很大(雪崩效果)
- 强抗碰撞: 已知原数据和MD5, 想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的
MD5的作用
MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一个定长的十六进制数字串).
MD5的算法原理
MD5以512位分组来处理输入的信息, 且每一分组又被划分为16个32位子分组, 经过了一系列的处理后, 算法的输出由四个32位分组组成, 将这四个32位分组级联后将生成一个128位散列值.
MD5的工具类
在java中有很多MD5实现, 其中Guava
和JDK
都有, 下面是一些例子
- 利用
Guava
中的工具
Hashing.md5().newHasher().putString(source, Charsets.UTF_8).hash().toString();
- 使用
JDK
的工具
下面这个工具完全是通过JDK
实现的, 没有使用第三方工具包
public class MD5Utils {
/**
* 对source按UTF_8编码进行md5签名
*
* @param source 待签名的原串
* @return md5签名值((32位小写16进制字符串)
*/
public static String encode(String source) {
return encode(source, "UTF-8");
}
/**
* 对source进行md5签名
*
* @param source 待签名的原串
* @param charsetName 字符编码
* @return md5签名值((32位小写16进制字符串)
*/
public static String encode(String source, String charsetName) {
String resultString = null;
try {
// 这里涉及SPI的相关内容
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] bytes = md5.digest(source.getBytes());
resultString = byteArrayToHexString(bytes);
} catch (Exception exception) {
throw new RuntimeException("MD5签名失败");
}
return resultString;
}
/**
* 字节数组转换成16进制字符串
*/
private static String byteArrayToHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder(2 * bytes.length);
for (byte b : bytes) {
sb.append(hexDigits[(b >> 4) & 0xf]).append(hexDigits[b & 0xf]);
}
return sb.toString();
}
private static final char[] hexDigits = "0123456789abcdef".toCharArray();
}
SHA1简介
SHA是美国国家安全局设计的,由美国国家标准和技术研究院发布的一系列密码散列函数。 安全哈希算法(Secure Hash Algorithm
)主要适用于数字签名标准(Digital Signature Standard DSS
)里面定义的数字签名算法(Digital Signature Algorithm DSA
)。对于长度小于2^64
位的消息, SHA1会产生一个160位的消息摘要。
SHA1的特点
- 不可以从消息摘要中复原信息
- 两个不同的消息不会产生同样的消息摘要(会有
10^48分之一
的机率出现相同的消息摘要, 一般使用时忽略)
SHA1算法流程
对于任意长度的明文, SHA1
首先对其进行分组, 使得每一组的长度为512位,然后对这些明文分组反复重复处理。
对于每个明文分组的摘要生成过程如下:
- 将512位的明文分组划分为16个子明文分组, 每个子明文分组为32位。
- 申请5个32位的链接变量,记为A、B、C、D、E。
- 16份子明文分组扩展为80份。
- 80份子明文分组进行4轮运算。
- 链接变量与初始链接变量进行求和运算。
- 链接变量作为下一个明文分组的输入重复进行以上操作。
- 最后,5个链接变量里面的数据就是SHA1摘要。
SHA1工具类
Guava
中同样有SHA1
的相关工具, 类似的还有sha256
, sha512
等散列工具
Hashing.sha1().newHasher().putString(source, Charsets.UTF_8).hash().toString();
MD5与SHA-1的比较
MD5
与SHA-1
都属于哈希散列算法, 都是从MD4
发展而来,它们的结构和强度等特性有很多相似之处, 他们的区别主要有下面这些:
- 安全性:
MD5
摘要长度128位(16字节),SHA-1
摘要长度160位(20字节) - 速度:
SHA1
的运算步骤(80步)比MD5
(64步)多了16步, 而且SHA1记录单元的长度比MD5多了32位,SHA1
速度大约比MD5
慢了25%
- 简易性: 两种方法都是相当的简单,在实现上不需要很复杂的程序或是大量存储空间。总体上来讲,
SHA1
对每一步骤的操作描述比MD5
简单