1.消息摘要
将任意长度的消息转换为固定长度的字符串,主要用途是确保数据的完整性和安全性,即验证数据在传输或存储过程中是否被篡改
2.MD5算法(消息摘要算法中的一种)
一种广泛使用的哈希函数,用于生成128位的消息摘要。它接受任意长度的输入,并输出固定长度的哈希值,通常用于验证数据完整性、数据签名、密码存储等领域
(1)设计原理
填充和长度标识:MD5算法将输入消息填充到512位的倍数,同时记录原始消息的长度
初始化向量:MD5算法使用四个32位的寄存器做为初始向量,用于存储中间计算的结果
四轮循环操作:MD5算法将输入消息分为若干个512位的数据块,每个数据块经过四轮循环操作,对寄存器中的值进行更新
四个非线性函数:MD5算法使用4个非线性函数对数据进行处理,增加了算法的复杂性和安全性
(2)算法流程
初始化寄存器:初始化4个32位的寄存器A/B/C/D,分别赋予特定的常量值
填充消息:将消息填充到512位的数据块,并记录消息的原始长度
处理数据块:将填充后的消息分为若干个512位的数据块,每个数据块进行四轮循环操作
更新寄存器:根据四轮循环操作的结果,更新寄存器A/B/C/D的值
生成哈希值:将最终的寄存器值按照A/B/C/D的顺序连接起来,即得到128位的MD5哈希值
(3)应用
数据完整性验证:用于数据完整性验证,确保数据在传输过程中没有被篡改。发送方在发送数据的时候会将其数据的md5哈希值和数据一起传输,接收放收到数据后重新计算md5哈希值,并与接收到的md5哈希值进行比较如果一致,则数据安全
数字签名:数字签名是一种用于验证数据来源和完整性的技术。发送方使用私钥对数据的MD5哈希值进行加密,生成数字签名并将其附加在数据中发送,接收方收到数据后私用发送方的公钥进行解密数字签名,在计算数据中md5哈希值并与解密后的数字签名进行比较,以验证数据的完整性和真实性
密码存储:md5算法可以在用于加密密码并存储在数据库中,当用户登录时,系统对用户输入的密码进行MD5哈希运算,然后与数据库中存储的md5哈希值进行比较,以验证密码的正确性。
文件校验:下载文件后计算文件的md5哈希值,与提供的md5值进行比较,以确保文件在传输过程中没有被篡改或损坏
3.MD5算法在登录中的应用(MD5+slat)
步骤:
生成随机盐值->合并密码与盐值->存储盐值与哈希
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Base64;
public class md5 {
public static String hashPassword(String password, byte[] salt) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(salt);
byte[] hashedPassword = md.digest(password.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(hashedPassword);
}
// 生成随机盐值
public static byte[] generateSalt() {
SecureRandom random = new SecureRandom();
byte[] salt = new byte[16];
random.nextBytes(salt);
return salt;
}
// 验证密码
public static boolean verifyPassword(String inputPassword, String storedHash, byte[] salt) throws Exception {
String hashedInput = hashPassword(inputPassword, salt);
return hashedInput.equals(storedHash);
}
public static void main(String[] args) throws Exception {
String password = "userPassword123";
// 生成盐值和哈希
byte[] salt = generateSalt();
String hashedPassword = hashPassword(password, salt);
// 存储盐和哈希
System.out.println("Salt (Base64): " + Base64.getEncoder().encodeToString(salt));
System.out.println("Hashed Password (Base64): " + hashedPassword);
// 验证密码
boolean isValid = verifyPassword("userPassword123", hashedPassword, salt);
System.out.println("Password valid: " + isValid); // 输出 true
}
}