Skip to content

哈希函数基础

目录

  1. 哈希函数概述
  2. 哈希函数的性质
  3. 常见的哈希函数
  4. 比特币中的哈希函数
  5. 哈希函数的应用
  6. 安全性考量
  7. 常见问题

哈希函数概述

什么是哈希函数

哈希函数是一种数学函数,它将任意长度的输入数据(称为"消息")映射到固定长度的输出值(称为"哈希值"、"摘要"或"指纹")。

哈希函数的基本形式:
H: {任意长度的数据} → {固定长度的数据}

例如:
H("Bitcoin") = 一个256比特的固定长度输出
H("Bitcoin is a peer-to-peer electronic cash system") = 同样是256比特的输出

哈希函数的直观理解

可以把哈希函数想象成一个"指纹机":

  • 输入:一个人(代表任意长度的数据)
  • 处理:提取生物特征
  • 输出:一个唯一的指纹(固定长度的代表性数据)

即使两个人看起来非常相似,他们的指纹也会完全不同。同样,即使两个输入数据仅相差一个字符,生成的哈希值也会完全不同。

为什么比特币需要哈希函数

比特币系统依赖哈希函数来实现:

  • 数据完整性验证:检测数据是否被篡改
  • 交易验证:验证交易的合法性
  • 区块链结构:链接不同的区块,形成不可篡改的链
  • 挖矿工作:找到满足条件的哈希值
  • 地址生成:从公钥生成比特币地址
  • 默克尔树:聚合区块中的所有交易

哈希函数的性质

1. 确定性(Deterministic)

定义:相同的输入总是产生相同的输出。

H(x) = H(x)  对任何输入 x 总是成立

例如:
H("Bitcoin") 今天计算结果 = H("Bitcoin") 明天计算结果 = H("Bitcoin") 10年后计算结果

为什么重要:确定性允许网络中的所有节点对相同数据进行哈希计算,得到相同结果,从而验证数据的一致性。

2. 快速计算(Efficient)

定义:哈希值可以快速计算,即使输入数据非常大。

计算速度示例:
- 计算 1 MB 数据的哈希值:毫秒级
- 计算 1 GB 数据的哈希值:秒级

为什么重要:在比特币网络中,节点需要快速验证交易和区块。如果哈希计算很慢,整个网络的效率会大幅下降。

3. 单向性(One-Way)

定义:从哈希值反推原始输入在计算上是不可行的。

已知:H(x) = y
要求:找到 x

结论:在没有其他信息的情况下,计算上不可行

为什么重要

  • 无法从比特币地址(哈希值)反推私钥(原始数据)
  • 无法从交易的哈希值反推交易的具体内容
  • 保证了比特币的安全性

4. 抗碰撞性(Collision Resistance)

定义:在实际中,不存在两个不同的输入产生相同的输出。

要求:找到 x1 ≠ x2 使得 H(x1) = H(x2)

对于安全的哈希函数:在实际中不可行

为什么重要

  • 如果两个不同的交易产生相同的哈希值,就无法区分它们
  • 如果两个不同的区块产生相同的哈希值,区块链就会混乱
  • 抗碰撞性是区块链完整性的基础

5. 雪崩效应(Avalanche Effect)

定义:输入的极小改变会导致输出的巨大改变。

示例:
H("Bitcoin") = a1b2c3d4e5f6...(256位的十六进制数)
H("bitcoin") = 9z8x7w6v5u4t...(完全不同!)

改变一个字符 B→b,哈希值中大约一半的位被改变

为什么重要

  • 无法通过部分数据修改来生成新的有效哈希值
  • 防止了对交易或区块的微小篡改
  • 使得任何欺骗企图都会被立即发现

常见的哈希函数

MD5(已废弃)

特性说明
输出长度128 位(16 字节)
发布年份1992 年
状态⚠️ 已废弃
已知问题已被找到碰撞,不再安全

为什么废弃

  • 在 2004 年,研究人员找到了 MD5 碰撞
  • 在 2008 年,利用伪造的 SSL 证书证实了 MD5 的弱点

SHA-1(弱化)

特性说明
输出长度160 位(20 字节)
发布年份1995 年
状态⚠️ 不再推荐
已知问题已被找到碰撞,仍可用但不安全

为什么弱化

  • 2017 年首次公开演示 SHA-1 碰撞(Google 项目)
  • 浏览器逐步放弃对 SHA-1 证书的支持

SHA-256(比特币使用)

特性说明
输出长度256 位(32 字节)
发布年份2001 年(SHA-2 家族)
状态推荐使用
应用领域比特币、以太坊、TLS 等
安全性目前认为是安全的

特点

  • 产生一个 256 比特的哈希值
  • 计算相对快速
  • 业界标准,经过数十年验证

SHA-512

特性说明
输出长度512 位(64 字节)
发布年份2001 年(SHA-2 家族)
状态推荐使用
应用领域需要更高安全性的应用

特点

  • 输出长度是 SHA-256 的两倍
  • 提供更高的安全裕度
  • 计算速度略低于 SHA-256

RIPEMD-160(比特币使用)

特性说明
输出长度160 位(20 字节)
发布年份1996 年
应用领域比特币地址生成
特点比特币特有的选择

在比特币中的角色

  • 用于从公钥生成比特币地址
  • 生成的地址更短(20 字节而不是 32 字节)
  • 结合 SHA-256 使用:RIPEMD160(SHA256(pubkey))

比特币中的哈希函数

比特币使用的两个主要哈希函数

1. SHA-256 的双重应用

在比特币中,SHA-256 通常被应用两次:

Double SHA-256:
result = SHA256(SHA256(data))

为什么双重应用?
- 增加安全性
- 防止 SHA-256 的某些已知弱点(如长度扩展攻击)
- 形成比特币的标准实践

应用场景

  • 计算交易 ID(Transaction ID, TXID)
  • 计算区块哈希
  • 验证工作量证明
  • 创建 Merkle 树

2. SHA-256 + RIPEMD-160 组合

比特币地址生成流程:
私钥 → 公钥 → SHA256(公钥) → RIPEMD160(结果) → 比特币地址

例如:
1. 公钥:0x0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
2. SHA256 结果:0x62E907B15CBF27D5425399FBEB6D815C69A4991968B79A88C39A7D4F44FC0F9E
3. RIPEMD160 结果:0x62E907B15CBF27D5425399FBEB6D815C69A4991968B79A88C39A7D4F44FC0F9E(20字节)
4. 最终地址:1A1z7agoat4eiX8nSBLw6KvLncesTiGQwP

哈希函数的应用

1. 交易完整性验证

场景:验证一笔交易是否被篡改

过程:
1. 接收方收到交易数据:
   {
     "input": "1A1z...",
     "output": "1B2y...",
     "amount": 1.5,
     "hash": "abc123def456..."
   }

2. 重新计算交易哈希:
   calculated_hash = SHA256(SHA256(transaction_data))

3. 对比哈希值:
   if calculated_hash == received_hash:
       ✅ 交易未被篡改
   else:
       ❌ 交易已被篡改,拒绝

2. 区块链结构维护

区块链结构:

区块 #100000
├── 区块头
│   ├── 版本号
│   ├── 前一区块哈希:abc...(指向区块 #99999)
│   ├── Merkle 根哈希:def...(所有交易的汇总)
│   ├── 时间戳
│   └── 难度目标
├── 交易数据
└── 区块哈希:xyz...(通过哈希区块头生成)



区块 #100001
├── 区块头
│   ├── 版本号
│   ├── 前一区块哈希:xyz...(指向区块 #100000)  ← 这形成了"链"
│   ├── Merkle 根哈希:ghi...
│   ├── 时间戳
│   └── 难度目标
├── 交易数据
└── 区块哈希:uvw...

链式结构的意义:
- 改变旧区块会改变其哈希值
- 这会使之后所有区块的"前一区块哈希"不匹配
- 整条链都会失效,容易被检测到

3. 挖矿工作量证明

挖矿的本质:找到一个符合条件的哈希值

步骤:
1. 矿工选择一些待打包的交易
2. 构造区块模板:
   {
     "previous_block_hash": "abc123...",
     "merkle_root": "def456...",
     "timestamp": 1234567890,
     "difficulty_target": 0x00000000ffff0000000000000000000000000000000000000000000000000000,
     "nonce": 0  ← 这个值会不断改变
   }

3. 不断改变 nonce(随机数),计算:
   block_hash = SHA256(SHA256(block_header))

4. 检查条件:
   if block_hash < difficulty_target:
       ✅ 找到有效区块!
   else:
       ✅ nonce += 1,继续尝试

示例:
- nonce = 0: 计算结果 = 0x9abc... (太大,不符合)
- nonce = 1: 计算结果 = 0x8def... (太大,不符合)
- nonce = 2: 计算结果 = 0x00000000abcd... (✅ 符合条件!)

4. Merkle 树构建

多笔交易的汇总过程:

交易列表:TX1, TX2, TX3, TX4

第一层(交易哈希):
H1 = SHA256(SHA256(TX1))
H2 = SHA256(SHA256(TX2))
H3 = SHA256(SHA256(TX3))
H4 = SHA256(SHA256(TX4))

第二层(配对哈希):
H12 = SHA256(SHA256(H1 + H2))
H34 = SHA256(SHA256(H3 + H4))

第三层(Merkle 根):
Merkle_Root = SHA256(SHA256(H12 + H34))

用途:
- 一个 32 字节的值(Merkle 根)代表了所有交易
- 任何交易的改变都会改变 Merkle 根
- 轻客户端(SPV)可以通过验证 Merkle 根来验证交易

5. 地址生成

从私钥生成比特币地址的完整过程:

1. 私钥
   priv_key = 0xe9873d79c6d87dc0fb6a5778633389f4453213303da61f20bd67fc233aa33262

2. 生成公钥(使用 ECDSA)
   pub_key = ECDSA_Generate(priv_key)
   = 0x0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798

3. SHA-256 哈希
   hash1 = SHA256(pub_key)
   = 0x62E907B15CBF27D5425399FBEB6D815C69A4991968B79A88...

4. RIPEMD-160 哈希
   hash2 = RIPEMD160(hash1)
   = 0x62E907B15CBF27D5425399FBEB6D815C69A4991968B79A88

5. Base58Check 编码
   address = Base58Check_Encode(0x00 + hash2)
   = 1A1z7agoat4eiX8nSBLw6KvLncesTiGQwP

最终结果:1A1z7agoat4eiX8nSBLw6KvLncesTiGQwP

安全性考量

哈希函数的安全隐患

1. 碰撞攻击(Collision Attack)

定义:找到两个不同的输入产生相同的输出

比如:
H(A) = H(B),其中 A ≠ B

对比特币的威胁:
- 如果两个不同的交易产生相同的哈希值,无法区分
- 攻击者可能伪造交易
- 影响:极高

防御:
- 选择抗碰撞性强的哈希函数(如 SHA-256)
- 及时更新到更强的算法(如 SHA-3)

2. 前向碰撞(Pre-image Attack)

定义:给定哈希值,找到产生该哈希值的输入

比如:
已知:hash_value = 0xabcd1234...
求:找到 x 使得 H(x) = hash_value

对比特币的威胁:
- 如果可以反推,就能从地址推出私钥
- 影响:极高

防御:
- 使用单向哈希函数
- SHA-256 目前被认为是抗前向碰撞的

3. 长度扩展攻击(Length Extension Attack)

定义:在已知 H(message) 的情况下,不知道 message,
但可以计算 H(message || additional_data) 而无需知道 message

对比特币的威胁:
- 直接威胁不大,因为比特币使用双重 SHA-256
- SHA256(SHA256(data)) 对长度扩展有天然的防护

防御:
- 使用双重哈希(比特币的做法)
- 使用 HMAC 等带密钥的哈希构造

哈希函数的选择标准

比特币选择 SHA-256 和 RIPEMD-160 的理由:

标准SHA-256RIPEMD-160
安全性✅ 经过充分验证✅ 经过充分验证
计算速度✅ 快速✅ 快速
输出大小256 比特160 比特
应用广泛度✅ 广泛(TLS、HTTPS等)⚠️ 较少
历史悠久度✅ 数十年验证✅ 数十年验证

常见问题

Q1: 为什么比特币使用双重 SHA-256?

A:

  1. 安全性增强:两次哈希比一次更难破解
  2. 防止长度扩展攻击:SHA-256 存在已知的长度扩展弱点,双重应用可以防御
  3. 历史传统:中本聪的设计选择,经过验证
  4. 兼容性:改变会导致所有现有地址和交易失效

Q2: 哈希碰撞是否会导致比特币失败?

A:

  • 短期:SHA-256 的碰撞在计算上目前不可行
  • 长期风险:如果 SHA-256 被破解,比特币可以升级到 SHA-3
  • 不是致命的:比特币社区已经为此做了准备,可以通过软分叉升级

Q3: 为什么比特币地址的长度不是 32 字节?

A:

  • SHA-256 输出 32 字节(256 位)
  • RIPEMD-160 输出 20 字节(160 位)
  • 原因:
    1. 减少地址长度,便于使用
    2. 提高隐私性(更难追踪密钥)
    3. 平衡安全性和实用性

Q4: 两个不同的输入会不会碰撞?

A:

  • 理论可能性:存在,但概率极低
  • 数值示例
    • SHA-256 可能的输出数:2^256(约 1.16 × 10^77)
    • 宇宙中的原子数:约 10^80
    • 概率:极其渺茫
  • 实际中:视为不可能

Q5: 量子计算会威胁 SHA-256 吗?

A:

  • Grover 算法威胁:理论上可以加速碰撞查询
  • 影响程度:减半输出大小的安全性(256 比特 → 128 比特安全性)
  • 仍然安全:128 比特的安全性仍然足够强大
  • 长期应对:比特币社区已在研究量子抗性算法