常见的密码散列函数算法:MD系列算法,SHA系列算法
一、什么是MD5?
MD5是一种被广泛使用的密码散列函数
,可以产生出一个128位(16字节)的散列值
(hash value),用于确保信息传输完整一致;
1、什么是密码散列函数
我们知道md5基于密码散列函数,他是散列函数的一种,而散列函数的有几个特点,决定了md5的特性;
1、单向性
:密码散列函数是一种单向函数,所以使得很难进行反推出原来的数据是什么。这种单向性使得它在存储密码等敏感信息就很受用;
2、固定输出长度
:不论输入大小如何,密码散列函数都生成相同长度的输出。例如,MD5算法的输出是128位(通常以32个十六进制数字表示)。
3、雪崩效应
:原数据只要有微小改动,其散列值也会有很大的不同
4、高效性:
计算散列值通常非常快速;
5、唯一性:
密码散列函数几乎不可能产生相同的散列值,但是后来被发现了md5的碰撞漏洞,不过呢,个人感觉这个是理论上存在的,实际现实中几乎不太可能遇到;
二、MD5的特点
1、压缩性
任意长度的数据,算出的MD5值长度都是固定的;
2、抗修改性
原数据改动再小,在md5的值上变化也是相当大的;
3、强抗碰撞性:
想找到两个不同的数据,使它们具有相同的MD5值,是非常困难的
4、弱抗碰撞性:
已知原数据和其MD5值,想找到一个具有相同MD5值的数据是非常困难的
MD5的应用广泛,包括确保文件完整性
、数据(如密码)存储
等。
什么是MD5碰撞?
即不同的输入数据会产生了相同的MD5值,我们则认为他们存在碰撞。因此即使Md5基于散列函数下,想找到两个不同的原数据,但具有相同MD5值是很困难,但因为他存在碰撞性弱点,就使得它不再适合用于需要高度安全性的场合,如密码存储或数字签名。在这些场合,更安全的算法如SHA-256
或SHA-3
通常被推荐使用;
使用场景:
1、密码存储的场景,我们会发现在一些项目中我们仍然会使用md5来保持我们用户的密码,那是因为我们在此基础上会加盐等其他机制,来加强我们的安全性;弥补md5的不足;
注:“加盐”是指在散列(如哈希处理)之前,将散列内容(例如密码)的任意固定位置插入特定的字符串。这个在散列中加入字符串的方式称为“加盐”。
2、文件完整性校验
当要发送一个文件时,发送方可以先计算该文档的MD5值(记作A),并将此值随文档一起发送给接收方。接收方在收到文档后,也计算其MD5值(记作B)。如果A与B一致,则说明文档在传输过程中未被篡改
三、代码中如何实现
在编程中,许多编程语言都提供了MD5的库或函数,可以方便地计算数据的MD5值。
例如🌰:
在Python
中,可以使用hashlib模块
来计算MD5值;
import hashlib
def get_md5_hash(input_string):
# 创建一个md5 hash对象
md5 = hashlib.md5()
# 更新要计算哈希的数据
md5.update(input_string.encode('utf-8'))
# 获取十六进制表示的哈希值
return md5.hexdigest()
# 示例
input_string = "Hello, World!"
md5_hash = get_md5_hash(input_string)
print("MD5 hash of \"{}\" is: {}".format(input_string, md5_hash))
Java
中则使用java.security.MessageDigest
类来计算数据的MD5值;
public static String getMD5Hash(String input) {
try {
// 获取MD5 MessageDigest实例
// 方法是通用的,参数中可以替换成其他算法,如"SHA-1", "SHA-256"
MessageDigest md = MessageDigest.getInstance("MD5");
// 更新要计算哈希的数据
byte[] messageDigest = md.digest(input.getBytes(StandardCharsets.UTF_8));
// 将字节数组转换为十六进制字符串
StringBuilder hexString = new StringBuilder();
for (byte b : messageDigest) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
使用 MessageDigest 的一般步骤包括:
导入 java.security.MessageDigest
类。
调用getInstance()
方法创建 MessageDigest 对象,并指定所需的哈希算法。
调用 update()
方法输入需要计算摘要的数据。
调用 digest()
方法计算哈希值。
还有就是我们容易搞混的概念,MD5本身并不是一种加密算法也不是加密哈希算法,而是一种单向哈希函数
,也是密码散列函数
,也叫消息摘要算法
,他只是将数据生成一个哈希值
,而并不能再将哈希值还原,所以,MD5也没有“解密”的概念;