md5不是加密算法, 请不要再分不清加密算法和摘要了!

300 阅读5分钟

screenshot-20250123-171154.png

screenshot-20250123-171211.png

image.png 上面两张图片, 是我在看一个讨论服务端密码安全解决方案文件里,有人讲的。相当大一部分人都搞不清楚什么叫做加密, 什么叫做摘要。

就连撰写那篇文章的作者也是傻傻的把md5说成加密算法。很不严谨。评论区里更是无一人去纠正作者的说辞。

那么我来为大家讲解一下什么是md5,什么是加密, 什么是摘要。

MD5

MD5是hash算法的一种, 他能将一定长度的十六进制字符内容, 通过一系列位运算、压缩函数等步骤,转换为指定长度的十六进制字符串。用于数据完整性校验。

什么是哈希算法

HASH算法是属于摘要算法的大类里。无论HASH的过程是简单,还是复杂,本质就是对原本内容的删减。 常见的hash算法如: sha-1, sha-256, md5。

hash算法都有一个共性,就是将无论多长的内容,都会转换为一个指定长度的字符串。

什么是摘要

比如: 我爱稀土掘金。编写一个简单的摘要算法函数, 输出只取偶数下标的字符进行拼接操作。输出内容为: "爱土金"。

fn even_index_summary(input: &str) -> String {
    let mut result = String::new(); // 创建一个空的字符串用于存储结果

    // 遍历字符串的字符和它们的索引
    for (index, ch) in input.chars().enumerate() {
        if index % 2 == 0 { // 如果索引是偶数
            result.push(ch); // 将字符追加到结果字符串中
        }
    }

    result // 返回结果字符串
}

那么你能根据摘要的内容去还原出原本的内容吗?

答案是: 不能, 或者还原出来的内容已经面目全非。

如: 我还原出来的,可能结果: 你爱粪土如金...

所以MD5为什么被称为不可逆的算法了。破解MD5摘要后的密码也只能通过彩虹表攻击等方案。

但是, 现代的密码md5后 会通过 agen2 + 加盐值等盐值计算方案,现在彩虹表攻击基本已经不起效了。只有一些比较远古未维护的网站可能会有这样的安全风险。

什么是加密算法

加密个人理解就是,把原本的内容通过一系列算法, 转换为另外一种内容。本质上是原有内容的破坏,而不是删除。 这是与摘要算法上的本质区别。

常见的加密算法比如: Base64 、AES等。这些算法都是可逆的。

简单加密算法实现

下面来看两段简单的加密和解密算法的实现。

将每个字符的Unicode码点乘以100后,直接转换为十六进制字符串。

// 加密函数
fn encrypt(input: &str) -> String {
    let encrypted = input.chars()
        .map(|c| {
            let code_point = c as u32 * 100;
            format!("{:X}", code_point) // 转换为十六进制
        })
        .collect::<Vec<String>>()
        .join(""); // 不使用逗号分隔
    encrypted
}

每个字符的十六进制表示长度是固定的(u32的十六进制长度为8)。 使用chunks方法将加密后的字符串按固定长度分段。 将每段十六进制字符串解析为十进制数字,除以100还原为原始Unicode码点,再转换为字符

// 解密函数
fn decrypt(encrypted: &str) -> String {
    let mut decrypted = String::new();
    let hex_len = 8; // 每个字符的十六进制表示长度(u32的十六进制长度为8)

    for chunk in encrypted.as_bytes().chunks(hex_len) {
        let hex_str = std::str::from_utf8(chunk).unwrap();
        let code_point = u32::from_str_radix(hex_str, 16).unwrap() / 100;
        decrypted.push(std::char::from_u32(code_point).unwrap());
    }

    decrypted
}

现在来run一哈。

fn main() {
    println!("请输入一个字符串进行加密:");
    let mut input = String::new(); // 输入: Hello
    io::stdin().read_line(&mut input).expect("读取失败");
    let input = input.trim();

    // 加密
    let encrypted = encrypt(input);
    println!("加密后的字符串:{}", encrypted); // "1C2027742A302A302B5C"

    // 解密
    let decrypted = decrypt(&encrypted);
    println!("解密后的字符串:{}", decrypted); // "hello"
}

是不是看起来有那么一回事了呢? 不过这个加密算法的密度还是太低了。安全程度还是太低了。 知识单纯让大家明白一下,什么是加密。

最后总结

1. MD5算法
  • 定义:MD5是一种哈希算法,属于摘要算法的一种。
  • 原理:它通过一系列位运算和压缩函数,将任意长度的输入数据转换为固定长度的十六进制字符串。
  • 用途:主要用于数据完整性校验,例如验证文件或数据在传输过程中是否被篡改。
  • 不可逆性:MD5是不可逆的,无法从输出结果直接还原原始数据。例如,通过MD5摘要后的密码无法直接被还原,只能通过暴力破解(如彩虹表攻击)尝试匹配。
2. 哈希算法与摘要算法
  • 哈希算法:是一种特殊的摘要算法,通过特定的算法将输入数据转换为固定长度的输出。
  • 摘要算法:是一类算法的总称,其核心是对原始数据进行“压缩”或“删减”,生成一个简化的表示形式。例如,通过提取偶数下标的字符生成摘要内容,这种摘要过程是不可逆的。
3. 总结
  • 澄清概念:加密和摘要(哈希)是两个完全不同的概念。加密是可逆的,用于保护数据的机密性;摘要(哈希)是不可逆的,用于验证数据的完整性。
  • 现代安全实践:在密码存储中,应避免使用MD5等不安全的哈希算法,而是采用加盐和更安全的哈希算法(如Argon2)来保护用户密码。