1. 简介

在现代数字系统中,安全问题日益突出,攻击手段层出不穷。为应对这些威胁,学术界和工业界纷纷提出各种安全机制,逐个击破不同类型的攻击。

哈希(Hashing)就是其中一种重要的安全机制。 它广泛用于保障数据的完整性、隐私性和真实性。哈希通过特定的数学函数,将任意长度的数据转换为固定长度的输出,从而实现数据摘要、身份验证等功能。

但在实际应用中,仅仅使用一次哈希算法往往不够安全。因此,加盐哈希(Salted Hashing) 应运而生,通过在原始数据中加入随机值(salt)并多次哈希处理,大大提升了安全性。

本文将介绍:

  • 哈希的基本概念
  • 简单哈希的工作原理及其优缺点
  • 加盐哈希的原理和优势
  • 两者之间的对比与适用场景

2. 哈希基础

哈希是一种将任意长度的输入数据转换为固定长度输出的机制。输出结果通常称为 哈希值(Hash Value)哈希码(Hash Code)摘要(Digest)

2.1 哈希函数的特性

  • 易于计算:给定输入,快速得到输出
  • 不可逆性(One-way):无法从哈希值反推出原始输入
  • 抗冲突性(Collision Resistance):不同输入尽可能不生成相同输出
  • 均匀分布:输出值在可能范围内分布均匀,避免聚集

⚠️ 注意: 哈希冲突不可避免。因为输入空间无限,而输出空间有限。因此,哈希函数的设计目标是最小化冲突发生的概率

2.2 哈希的应用场景

  • ✅ 密码存储(如用户密码)
  • ✅ 数据结构(如 HashMap、HashSet)
  • ✅ 数字签名与文件完整性校验

下面这张图形象地展示了哈希的基本过程:

Hashing


3. 简单哈希(Simple Hashing)

简单哈希是指对输入数据只进行一次哈希运算。

3.1 工作流程

以用户注册为例:

  1. 用户输入密码
  2. 系统对密码进行一次哈希运算
  3. 将哈希值存储在数据库中

登录时:

  1. 用户输入密码
  2. 系统再次进行哈希运算
  3. 与数据库中的哈希值比对,一致则登录成功

SimpleHashing

3.2 优点

  • ✅ 速度快,计算开销小
  • ✅ 实现简单,适合资源受限的环境

3.3 缺点

  • 易受彩虹表攻击(Rainbow Table Attack)
  • 易受暴力破解攻击(Brute Force Attack)
  • ❌ 相同密码会生成相同哈希值,暴露用户信息关联性

4. 加盐哈希(Salted Hashing)

加盐哈希在哈希过程中加入一个随机值(salt),再进行多次哈希处理。

4.1 工作流程

仍以密码存储为例:

  1. 用户注册时,系统生成一个随机 salt(如 abc123
  2. 将密码与 salt 拼接:password + salt
  3. 对拼接后的字符串进行第一次哈希
  4. 可选地进行多次哈希与还原(reduction)操作
  5. 最终哈希值与 salt 一同存储在数据库中

登录时:

  1. 用户输入密码
  2. 使用数据库中对应的 salt 拼接
  3. 执行相同哈希流程
  4. 比对最终哈希值

SaltedHashing

4.2 示例代码(Java)

import java.security.SecureRandom;
import java.security.MessageDigest;
import java.util.Base64;

public class SaltedHashExample {
    public static String hashPassword(String password, String salt) throws Exception {
        String saltedPassword = password + salt;
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] hash = md.digest(saltedPassword.getBytes());
        return Base64.getEncoder().encodeToString(hash);
    }

    public static String generateSalt() {
        byte[] salt = new byte[16];
        new SecureRandom().nextBytes(salt);
        return Base64.getEncoder().encodeToString(salt);
    }

    public static void main(String[] args) throws Exception {
        String password = "mySecurePassword123";
        String salt = generateSalt();
        String hashed = hashPassword(password, salt);
        System.out.println("Salt: " + salt);
        System.out.println("Hashed Password: " + hashed);
    }
}

4.3 优点

  • ✅ 更强的安全性,抵御彩虹表攻击
  • ✅ 即使密码相同,由于 salt 不同,哈希值也不同
  • ✅ 可配置多次哈希迭代,提高破解成本

4.4 缺点

  • ❌ 计算开销更大,响应时间更长
  • ❌ 需要额外存储 salt 值

5. 对比总结

特性 简单哈希 加盐哈希
哈希次数 1 次 多次
计算开销
抵御彩虹表攻击
抵御暴力破解
密码重复问题
适用场景 资源受限、安全性要求不高 高安全性场景(如用户密码)

6. 总结

本文详细介绍了 简单哈希加盐哈希 的原理、流程、优缺点以及典型应用场景。

简单哈希 实现简单、速度快,适合低安全要求的场景。

加盐哈希 安全性更高,能有效抵御常见攻击,是现代系统中推荐使用的密码存储方式。

最终选择哪种方式,取决于系统对性能和安全性的权衡。 在涉及用户敏感信息的场景中,加盐哈希是更优的选择



原始标题:Simple Hashing vs. Salted Hashing