从零开始了解 TLS 1.3 系列笔记(三)—— 实用密码学之「哈希函数」

TL;DR

  1. 哈希函数将任意大小的输入数据不可逆地映射为固定大小的结果, 该结果称为哈希值.
  2. 加密哈希函数要求映射冲突的发生概率非常低, 以至于在实际应用中可以忽略不计, 保证无法伪造数据和原始数据具备一致的哈希值.
  3. 加密哈希函数只能保证数据完整性, 不能保证数据真实性.
  4. 现代哈希函数包括 SHA-2, SHA-3, BLAKE2 / BLAKE3 等; 应当避免使用 MD5, SHA-1 等被认为不安全的哈希函数.

前言

在本章中, 我们将介绍哈希函数的基本概念, 以及常见的安全哈希算法. 哈希函数在 TLS 协议中被广泛使用, 例如在数字签名算法、消息认证码 (MAC) 和密钥派生函数 (KDF) 中都有应用.

哈希函数与加密哈希函数

在计算机编程中, 哈希函数将输入不可逆地映射到一个整数. 通常不同的输入映射到不同的输出; 在密码学中, 哈希函数将任意大小的输入数据转换为因算法而异的固定大小的结果, 该结果称为哈希值. 计算机密码学中使用的哈希函数称为 “加密哈希函数”.

对于哈希函数, 我们期待不同输入映射到不同输出, 但由于输入空间无限而输出空间有限, 不可避免地会发生冲突 (也称哈希碰撞); 而对于一个合格的加密哈希函数, 我们要求这个冲突的发生概率非常非常低, 以至于在实际应用中可以忽略不计.

一个理想的加密哈希函数应当具有如下特性:

  • 确定性, 即对同样的输入, 应该总是产生同样的输出;
  • 快速, 计算速度要足够快;
  • 难以分析, 即对输入的任何微小改动, 都应该使输出完全发生变化;
  • 不可逆, 即从其哈希值逆向演算出输入值应该是不可行的, 这意味着没有比暴力破解更好的破解方法;
  • 抗碰撞, 即几乎不可能找到具有相同哈希值的两条不同消息.

现代加密哈希函数, 如 SHA-2 和 SHA-3, 都至少在当前已知的攻击方法下满足上述特性.

加密哈希函数的应用

加密哈希函数有很多应用, 其中最常见的包括:

  1. 数据完整性校验

这是加密哈希函数最常见的应用, 此时的哈希值作为 “校验和” (checksum). 例如, 当从互联网下载文件, 下载完毕后计算文件字节流的 SHA256 校验和跟官方公布的一致, 那就说明文件没有损坏.

但需要指出: 哈希函数自身不能保证文件的真实性, 目前来讲, 从网上下载的文件的真实性通常是 TLS 协议要保证的, 它确保你看到的网站所公布的「SHA256 校验和」是未被篡改的.

  1. 密码存储

加密哈希函数还被用于密码的安全存储, 以避免因直接存储明文密码、而某日数据库泄露导致密码泄露的问题.

应当使用专门设计的安全哈希算法, 如 Scrypt, 计算用户密码的哈希值再持久化保存. 这种算法往往被设计为 CPU 密集和/或内存密集的, 以及难以并行化的, 提高单次计算的耗时, 以增加暴力破解的成本.

  1. 唯一 ID

将任意长的文件内容哈希化生成一个定长的唯一的 ID, 用以索引等.

  1. 伪随机数生成

哈希函数也可以用来生成伪随机数, 例如, 可以将一个随机种子值(从随机事件中收集熵, 如随机的鼠标移动或键盘输入)并附加一个值然后哈希化, 得到一个伪随机数. 可将结果附加一个值再哈希化, 得到另一个伪随机数. Linux 内核的 /dev/urandom 就是基于此原理实现的.

  1. 工作量证明 (PoW, Proof of Work) 算法

略.

安全哈希算法

以下简要介绍几种常见的安全哈希算法.

SHA-2

依据哈希位数, 可分为 SHA-256, SHA-384 和 SHA-512 等若干变体. SHA-2 基于 “Merkle-Damgård 构造” , 目前被认为高度安全.

示例:

SHA-256('hello') = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
SHA-384('hello') = 59e1748777448c69de6b800d7a33bbfb9ff1b463e44354c3553bcdb9c666fa90125a3c79f90397bdf5f6a13de828684f
SHA-512('hello') = 9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043

SHA-3

比 SHA-2 更安全, 不容易遭受长度扩展攻击; 在 TLS 1.3 中并未使用.

BLAKE2 / BLAKE3

BLAKE2 / BLAKE3 安全性与 SHA-3 相当, 但针对现代硬件进行高度优化, 哈希速度比 SHA-3 快得多; 在 TLS 1.3 中并未使用.

其他

如中国的商密系列 SM3 / SM4 等.

不安全的哈希函数

应当避免使用以下被认为不安全或安全性有争议的的哈希算法: MD2、MD4、MD5、SHA-0、SHA-1、Panama、HAVAL (有争议的安全性, HAVAL-128 发现冲突)、Tiger (有争议, 发现弱点)、SipHash (它不是加密哈希函数).

本章小结

  1. 哈希函数将任意大小的输入数据不可逆地映射为固定大小的结果, 该结果称为哈希值.
  2. 加密哈希函数要求映射冲突的发生概率非常低, 以至于在实际应用中可以忽略不计, 保证无法伪造数据和原始数据具备一致的哈希值.
  3. 加密哈希函数只能保证数据完整性, 不能保证数据真实性.
  4. 现代哈希函数包括 SHA-2, SHA-3, BLAKE2 / BLAKE3 等; 应当避免使用 MD5, SHA-1 等被认为不安全的哈希函数.

部分参考文献