# 哈希函数是什么？定义、例子与常见误区

> 哈希函数（密码学哈希函数）把任意长度的输入映射为固定长度的摘要，且在计算上无法逆推输入，也无法找到摘要相同的两个输入。

Source: https://ssl.sh/zh/glossary/hash-function/
Last updated: 2026-11-10

密码学哈希函数接受任意长度的数据，输出固定长度的摘要，例如 [SHA-256](https://ssl.sh/zh/glossary/sha-256/) 输出 256 位。它必须具备抗原像性（给定摘要找不到对应输入）、抗第二原像性和抗碰撞性（找不到两个摘要相同的输入），输入哪怕只改一位，摘要也会面目全非。当前常用的有 SHA-256、SHA-384 和 SHA-3；MD5 和 [SHA-1](https://ssl.sh/zh/glossary/sha-1/) 的抗碰撞性已被攻破。

## 为什么重要
哈希几乎支撑着 TLS 和 PKI 的每个环节。证书上的[数字签名](https://ssl.sh/zh/glossary/digital-signature/)签的其实是证书内容的哈希，一旦哈希可以被实际碰撞，攻击者就可能把 CA 的签名"挪用"到伪造证书上；2008 年研究人员正是利用 MD5 碰撞做出了一张伪造的 CA 证书。此外，证书指纹、HMAC 与 HKDF 密钥派生、Finished 消息对握手记录的校验，以及证书透明度日志的 Merkle 树，都依赖哈希函数。国密体系中的 SM3 也属于这一类算法。

## 例子
只改一个字符，摘要就完全不同：

```bash
printf 'example.com' | openssl dgst -sha256
printf 'example.con' | openssl dgst -sha256
openssl x509 -in example.com.crt -noout -fingerprint -sha256
```

## 常见误区
- **哈希就是一种加密。** 哈希没有密钥，也无法解密。保存用户密码应使用 bcrypt、Argon2 这类专门的慢速函数，而不是直接用快速哈希。
- **指纹对得上，证书就可信。** 指纹只用来唯一标识某一张证书，是否可信要靠证书链验证。
- **输出够长的哈希就够安全。** MD5 有 128 位、SHA-1 有 160 位，但两者都已出现实际碰撞，关键在算法本身而不只是长度。

## 相关术语

- [SHA-256](https://ssl.sh/zh/glossary/sha-256/): SHA-256 是 SHA-2 哈希家族中输出 256 位摘要的成员，由 NIST FIPS 180-4 规定，是当今 TLS 证书签名和指纹的标准哈希算法。
- [SHA-1](https://ssl.sh/zh/glossary/sha-1/): SHA-1 是 1995 年发布的 160 位哈希函数，已出现实际可行的碰撞攻击，公开信任的 TLS 证书早已不再允许使用它签名。
- [数字签名](https://ssl.sh/zh/glossary/digital-signature/): 数字签名是用私钥对消息计算出的一个值，任何持有对应公钥的人都能验证它，从而确认消息来源和内容未被篡改。
- [证书指纹](https://ssl.sh/zh/glossary/certificate-fingerprint/): 证书指纹是对证书 DER 编码计算出的哈希值（通常用 SHA-256），用来唯一标识一张证书，它本身并不存储在证书里。
- [AEAD](https://ssl.sh/zh/glossary/aead/): AEAD 是带关联数据的认证加密算法，一次运算同时完成数据加密和完整性认证，并能保护不加密的附加数据不被篡改。
- [证书透明度](https://ssl.sh/zh/glossary/certificate-transparency/): 证书透明度（CT）是一套公开、只可追加的日志系统，记录所有公开信任的 TLS 证书，让任何人都能审计 CA 签发了什么。
