哈希函数基础

哈希函数(Hash Function)是一种将任意长度输入转换为固定长度输出的单向函数。

核心特性

  1. 确定性:相同输入始终产生相同输出
  2. 单向性:无法从哈希值反推原始输入
  3. 抗碰撞性:难以找到两个不同输入产生相同哈希
  4. 雪崩效应:输入微小变化导致哈希大幅变化

常见哈希算法

1. SHA-2 系列

SHA-2 是目前最安全的哈希算法系列,由 NSA 设计。

算法 输出长度 安全性 推荐用途
SHA-256 256 位 一般用途
SHA-384 384 位 更高 高安全需求
SHA-512 512 位 最高 极端安全场景

OpenSSL SHA-256 示例:

1
2
3
4
5
6
# 计算文件哈希
openssl dgst -sha256 file.txt
# 输出: SHA256(file.txt)= abc123...

# 生成二进制哈希
openssl dgst -sha256 -binary file.txt | xxd -p

2. SHA-3

SHA-3 是 NIST 竞选产生的新标准,使用 Keccak 算法。

特点:

  • 与 SHA-2 结构不同
  • 提供额外的安全储备
  • 与 SHA-2 互补使用

3. MD5 与 SHA-1(不推荐)

算法 问题 状态
MD5 已被证明可碰撞 ❌ 应禁用
SHA-1 已被证明可碰撞 ❌ 应禁用

数字签名原理

数字签名结合哈希函数和非对称加密,实现:

  1. 数据完整性:验证数据未被篡改
  2. 身份认证:确认发送者身份
  3. 不可否认:发送者无法否认发送行为

工作流程

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
签名过程:
1. 计算消息哈希
2. 使用私钥加密哈希 → 签名
3. 发送消息 + 签名

验证过程:
1. 收到消息 + 签名
2. 计算消息哈希
3. 使用公钥解密签名 → 原始哈希
4. 对比两个哈希是否一致

OpenSSL 数字签名实战

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 1. 生成密钥对
openssl genrsa -out signer.key 2048
openssl rsa -in signer.key -pubout -out signer.pub

# 2. 签名文件(使用 SHA-256)
openssl dgst -sha256 -sign signer.key -out signature.bin file.txt

# 3. 验证签名
openssl dgst -sha256 -verify signer.pub -signature signature.bin file.txt
# 输出: Verified OK

# 4. 生成 PEM 格式签名(可读)
openssl dgst -sha256 -sign signer.key | base64 > signature.txt

生成独立签名文件

1
2
3
4
5
# 生成签名(不带消息)
echo -n "data to sign" | openssl dgst -sha256 -sign key.pem | base64 > sig.b64

# 验证
echo -n "data to sign" | openssl dgst -sha256 -verify pub.pem -base64 sig.b64

签名与加密的区别

特性 签名 加密
目的 认证 + 完整性 机密性
使用密钥 私钥签名 公钥加密
验证方式 公钥验签 私钥解密
保护对象 谁发送的 数据内容

安全实践

  1. 算法选择:SHA-256 或更高
  2. 私钥保护:签名私钥必须严格保护
  3. 证书绑定:使用数字证书绑定公钥和身份
  4. 时间戳:签名时加入时间戳
  5. 证书吊销检查:验证证书 validity

参考来源