# HPKP（HTTP 公钥固定）是什么？定义、例子与常见误区

> HPKP 是 RFC 7469 定义、现已废弃的 HTTP 响应头，要求浏览器只在证书链包含指定公钥时才接受该网站。

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

HPKP（HTTP Public Key Pinning，HTTP 公钥固定，[RFC 7469](https://www.rfc-editor.org/rfc/rfc7469)）允许网站发送 Public-Key-Pins 响应头，列出若干公钥的 SHA-256 哈希（SPKI pin）。在 max-age 秒内，只要证书链里不包含任何一个被固定的公钥，浏览器就拒绝连接，哪怕证书本身完全有效。RFC 要求至少提供一个备用 pin，对应当前证书链之外的密钥。

## 为什么重要
HPKP 是一个反面教材。密钥丢失、被迫更换 CA 或 pin 配错，都可能让用户在整个 max-age 期间无法访问，而且无法远程补救，这被称为“HPKP 自杀”；攻击者短暂控制网站后，甚至可以设置恶意 pin 来“绑架”网站。HPKP 的采用率一直很低，Chrome 72 已移除对它的支持。它想解决的问题，即受信任 CA 签发的冒用证书，如今主要由[证书透明度](https://ssl.sh/zh/glossary/certificate-transparency/)和 [CAA](https://ssl.sh/zh/glossary/caa/) 来应对。“固定”的思路如今主要保留在移动 App 的[证书锁定](https://ssl.sh/zh/glossary/certificate-pinning/)中，同样存在换证书时把老版本 App“锁死”的风险。

## 例子
计算一个 pin，以及当年网站会发送的响应头：

```bash
openssl x509 -in cert.pem -pubkey -noout \
  | openssl pkey -pubin -outform der \
  | openssl dgst -sha256 -binary | openssl enc -base64
```

```text
Public-Key-Pins: pin-sha256="<primary-key-hash>"; pin-sha256="<backup-key-hash>"; max-age=5184000; includeSubDomains
```

今天不要再部署这个响应头。

## 常见误区
- **HPKP 和 HSTS 是一回事。** HSTS 强制使用 HTTPS，HPKP 限制可接受的密钥。HSTS 仍然推荐使用，HPKP 已被 Chrome 移除。
- **只要续期时小心，固定叶子证书公钥就安全。** 续期换了新密钥而没有备用 pin 覆盖，就会触发锁死，许多网站正是这样把自己锁在门外的。
- **删掉响应头就能立刻解锁。** 浏览器会一直保留 pin，直到 max-age 到期。

## 相关术语

- [证书锁定](https://ssl.sh/zh/glossary/certificate-pinning/): 证书锁定是客户端侧的一项检查：只有服务器证书链中包含事先配置好的特定证书或公钥时，客户端才接受这次连接。
- [HSTS](https://ssl.sh/zh/glossary/hsts/): HSTS 是一个 HTTP 响应头，告诉浏览器在指定时间内只通过 HTTPS 访问该站点，并且遇到证书错误时不允许用户继续访问。
- [公钥](https://ssl.sh/zh/glossary/public-key/): 公钥是非对称密钥对中可以公开的一半，写在证书里，供他人验证由对应私钥生成的签名。
- [证书透明度](https://ssl.sh/zh/glossary/certificate-transparency/): 证书透明度（CT）是一套公开、只可追加的日志系统，记录所有公开信任的 TLS 证书，让任何人都能审计 CA 签发了什么。
- [密钥轮换](https://ssl.sh/zh/glossary/key-rotation/): 密钥轮换是按计划或在安全事件后，用新生成的密钥替换旧密钥，以限制密钥泄露造成损失的做法。
- [CAA 记录](https://ssl.sh/zh/glossary/caa/): CAA 记录是一种 DNS 记录，用来声明哪些证书颁发机构可以为该域名签发证书，所有公共 CA 签发前都必须检查。
