# PKCS#7是什么？定义、例子与常见误区

> PKCS#7 是一种用于签名和加密数据的格式，在 .p7b 或 .p7c 文件中常用来打包一组证书，不含私钥。

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

PKCS #7 以 RFC 2315 发布，后来由 IETF 发展为密码消息语法 CMS（RFC 5652），定义了签名数据、加密（封装）数据等受保护数据的容器。其中 SignedData 结构带有一个证书字段，只放证书、不含内容和签名的"仅证书"SignedData 就成了传递[证书链](https://ssl.sh/zh/glossary/certificate-chain/)的便捷方式。这类文件扩展名一般是 .p7b 或 .p7c，可以是带 `BEGIN PKCS7` 头的 [PEM](https://ssl.sh/zh/glossary/pem/)，也可以是二进制 DER。

## 为什么重要
一些 CA 和 Windows 工具会把签发的证书及中间证书打包成 .p7b 交付，Java keytool 导入 CA 回复时也接受 PKCS #7 证书链。[S/MIME](https://ssl.sh/zh/glossary/smime/) 邮件和 Windows Authenticode 代码签名用的也是同一种结构。部署到 nginx、Apache 等 Web 服务器时，一般要先把 .p7b 转成 PEM 证书链，并把站点证书放在最前面，因为这些服务器只读 PEM，不读 PKCS #7。

## 例子
```bash
openssl pkcs7 -in example.com.p7b -print_certs -out example.com-chain.pem
# 如果是二进制文件，加上：-inform DER
openssl crl2pkcs7 -nocrl -certfile fullchain.pem -out example.com.p7b
```

## 常见误区
- **.p7b 里有私钥。** 它只放证书（可选 CRL），从不包含私钥；私钥要一起迁移时用 PKCS #12。
- **.p7b 里的证书按链的顺序排列。** 证书字段是无序集合，生成 PEM 链时要自己按"站点证书在前"重新排序。
- **PKCS #7 只是证书格式。** 它的主要用途是签名和加密消息，打包证书只是附带用法。

## 相关术语

- [PEM](https://ssl.sh/zh/glossary/pem/): PEM 是一种把 DER 二进制数据做 Base64 编码、再用 BEGIN 和 END 行包起来的文本格式，是存放证书和私钥最常见的方式。
- [DER](https://ssl.sh/zh/glossary/der/): DER 是 ASN.1 的二进制编码规则，保证每个值只有唯一一种字节表示，X.509 证书和密钥都以它为基础。
- [证书链](https://ssl.sh/zh/glossary/certificate-chain/): 证书链是从网站终端证书经中间证书一直到受信任根证书的有序证书序列，每一张都由下一张签名。
- [S/MIME](https://ssl.sh/zh/glossary/smime/): S/MIME 是一种使用 X.509 证书和 CMS 格式对电子邮件进行端到端签名和加密的标准。
- [代码签名证书](https://ssl.sh/zh/glossary/code-signing-certificate/): 代码签名证书是带有 codeSigning 扩展密钥用途、用来给软件做数字签名，让用户能核实发布者身份和文件完整性的 X.509 证书。
- [CRT 文件](https://ssl.sh/zh/glossary/crt-file/): CRT 文件是存放 X.509 证书的 .crt 或 .cer 文件，内容可能是 PEM 文本，也可能是二进制 DER，取决于生成它的平台。
- [中间证书](https://ssl.sh/zh/glossary/intermediate-certificate/): 中间证书是由根证书（或上级中间证书）签发、用来签发网站证书的 CA 证书，服务器必须把它和网站证书一起发送给客户端。
