在计算机程序设计中,哈希函数(又名散列函数)把文本或者其他数据映射为整数。通常不同的输入对应不同的输出,但是有时候会发生碰撞(collision碰撞就是不同的输入对应相同的输出)。

加密哈希函数把文本或者二进制数据转化为固定长度哈希值,并且具有抗碰撞性不可逆性

软件工程里的哈希

在程序中哈希函数通常被用来实现数据结构hash-table(哈希表,或者关联数组,或者字典)。

python中的数据类型dict

1
dict={"name":"xiaoye","age":29}

加密哈希函数

在密码学中,哈希函数将任意大小的输入数据(例如文本消息)转换为固定大小的结果(例如256位),被称为哈希值(或哈希码、消息摘要)。在计算机密码学中使用的哈希函数(哈希算法)被称为“加密哈希函数”。SHA3-256就是一个加密哈希函数,把任意输入转化为256位,例如,我们可以使用它计算helloworld的哈希值。

1
2
3
4
import hashlib,binascii
sha3_256hash=hashlib.sha3_256('helloworld'.encode('ascii')).digest()
print("SHA3-256('helloworld') =", binascii.hexlify(sha3_256hash))
# output:92dad9443e4dd6d70a7f11872101ebff87e21798e4fbb26fa4bf590eb440e71b

安全哈希函数

在过去,软件开发人员提出了许多加密哈希算法。其中一些被破坏了(如MD5和SHA1),但仍有一些仍然是安全的(如SHA-2、SHA-3和BLAKE2)

SHA-2

SHA-2是一组强加密哈希函数:SHA-256(256位哈希)、SHA-384(384位哈希)、SHA-512(512位哈希)等等。

它基于加密概念Merkle–Damgård construction,被认为是高度安全的。SHA-2在美国作为官方密码标准发布。

SHA-2被开发人员和密码学广泛使用,被认为在密码学上足够强大,可以用于现代商业应用程序。

SHA-3

SHA-3(以及它的变体SHA3-224, SHA3-256, SHA3-384, SHA3-512)比同样散列长度的SHA-2(SHA-224, SHA-256, SHA-384, SHA-512)更加安全。例如,对于相同的散列长度(256位),SHA3-256SHA-256具有更多的加密强度。

SHA-3被认为是高度安全的,并作为美国官方推荐的加密标准发布。

SHA-256在比特币区块链中被广泛使用,例如用于识别交易散列,以及用于矿工所进行的挖掘工作证明。

不安全的哈希函数

旧的哈希算法如MD5SHA-0SHA-1被认为是不安全的。所以不要再使用这些哈希函数。

哈希函数的应用

文件完整性

用户从网上下载文件的过程中,为了保证文件是原始的,没有被损坏,一般文件提供方都会在网站上给出文件的哈希值(MD5值或者SHA256校验值等),这样用户下载文件后就可以用同样的哈希算法来计算哈希值,通过与官网的哈希值对比,就能知道文件是不是原始的。

例如openssl官网的下载页面分别给出了文件的SHA256SHA1两种哈希值

我下载了openssl-3.0.0-alpha7.tar.gz这个文件,在mac计算SHA1哈希值的命令如下

$ shasum -a 1 openssl-3.0.0-alpha7.tar.gz

输出的结果是1d05682f62b34038a37b196c7c43a21013f5f507,通过比对官网的SHA 1值,完全一样,说明下载的文件是原始的。

存储密码

哈希函数还可以用来存储密码和验证密码。开发者通常不会直接保存用户的明文密码,而是保存密码的hash值,这样防止保存密码的文件或数据库泄漏后,用户的密码也随之泄漏。当然,如果要更加安全的保存用户的密码,不能简单的使用MD5或者MD5+盐(salt),因为这些哈希函数被证明是不安全的,需要用密钥派生函数(Key derivation function)。

生成唯一ID (Generate Unique ID)

为文档/消息生成几乎唯一的ID。加密哈希函数可以基于文档的内容近乎唯一地标记文档。理论上任何哈希函数都可能发生碰撞,但是发生碰撞的及其小,所以大多数系统(例如git)假设他们使用的哈希函数是没有碰撞的。

代码版本管理工具git会为每一个版本提交创建一个commit值,这个值是一个SHA-1哈希。

工作量证明 (Proof-of-Work,PoW)

一般要求用户进行一些耗时适当的复杂运算,并且答案能被服务方快速验算,以此耗用的时间、设备与能源做为担保成本,以确保服务与资源是被真正的需求所使用。工作量证明最常用的技术原理是散列函数。由于输入散列函数h()的任意值n,会对应到一个h(n)结果,而n只要变动一个比特,就会引起雪崩效应,所以几乎无法从h(n)反推回n,因此借由指定查找h(n)的特征,让用户进行大量的穷举运算,就可以达成工作量证明。现时此技术成为了加密货币的主流共识机制之一,如比特币所采用的技术。

伪随机数生成

哈希值可以用作随机数。

参考:

  1. 维基百科-工作量证明
  2. cryptobook
  3. 《深入浅出HTTPS:从原理到实战》
⬆︎TOP