什么是 PKCS#12?

PKCS#12(也称为 PFX)是公钥密码学标准之一,定义了一种用于存储多个密码学对象的文件格式。在实际应用中,PKCS#12 文件通常用于:

  • 打包服务器证书和私钥
  • 包含证书链(CA 证书)
  • 在不同系统之间迁移证书和私钥

与 PEM 格式相比,PKCS#12 将证书、私钥和证书链打包成单个二进制文件,并支持加密保护。


基本用法

从私钥和证书创建 PKCS#12

最常见的用法是将私钥和服务器证书打包成 PKCS#12 文件:

1
2
3
4
5
6
openssl pkcs12 -export \
    -out server.p12 \
    -inkey server.key \
    -in server.crt \
    -name "Server Certificate" \
    -passout pass:changeit

参数说明:

  • -export:创建 PKCS#12 文件
  • -out server.p12:输出文件名
  • -inkey server.key:输入的私钥文件
  • -in server.crt:输入的证书文件
  • -name "Server Certificate":证书的友好名称(可选)
  • -passout pass:changeit:导出密码

执行后会在当前目录生成 server.p12 文件。

查看 PKCS#12 文件内容

创建后可以使用以下命令查看文件信息:

1
openssl pkcs12 -in server.p12 -info -noout -passin pass:changeit

输出示例:

1
2
3
4
5
6
MAC: sha256, Iteration 2048
MAC length: 32, salt length: 8
PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256
Certificate bag
PKCS7 Data
Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256

输出显示:

  • MAC(Message Authentication Code):使用 SHA256
  • 私钥使用 AES-256-CBC 加密
  • 密钥派生使用 PBKDF2,迭代次数 2048

包含证书链

添加 CA 证书链

如果需要将 CA 证书链也包含在 PKCS#12 文件中,使用 -certfile 选项:

1
2
3
4
5
6
7
openssl pkcs12 -export \
    -out server-with-chain.p12 \
    -inkey server.key \
    -in server.crt \
    -certfile ca-chain.crt \
    -name "Server with Chain" \
    -passout pass:changeit

-certfile 指定的文件可以包含一个或多个 CA 证书。

从 PKCS#12 提取 CA 证书

从已有的 PKCS#12 文件中提取 CA 证书:

1
openssl pkcs12 -in server.p12 -cacerts -nokeys -out ca-cert.pem -passin pass:changeit

参数说明:

  • -cacerts:仅提取 CA 证书
  • -nokeys:不提取私钥

提取证书和私钥

提取证书

从 PKCS#12 文件中提取服务器证书:

1
openssl pkcs12 -in server.p12 -clcerts -nokeys -out server-cert.pem -passin pass:changeit

参数说明:

  • -clcerts:仅提取客户端/服务器证书(不包括 CA 证书)
  • -nokeys:不提取私钥

提取私钥

从 PKCS#12 文件中提取私钥:

1
openssl pkcs12 -in server.p12 -nocerts -out server-key.pem -passin pass:changeit -passout pass:newpassword

参数说明:

  • -nocerts:不提取证书
  • 提取私钥时需要设置新的导出密码(-passout pass:newpassword

⚠️ 警告:提取的私钥文件需要妥善保管,设置合适的文件权限:

1
chmod 600 server-key.pem

加密选项

指定加密算法

可以使用 -keypbe-certpbe 选项分别指定私钥和证书的加密算法:

1
2
3
4
5
6
7
openssl pkcs12 -export \
    -out server-aes.p12 \
    -inkey server.key \
    -in server.crt \
    -keypbe aes-256-cbc \
    -certpbe aes-256-cbc \
    -passout pass:changeit

支持的加密算法包括:

  • aes-256-cbc(推荐)
  • aes-128-cbc
  • des(已不推荐使用)
  • 3des(已不推荐使用)

兼容旧版系统

对于需要兼容旧版系统(Windows Server 2003、Java 6 等)的情况,使用 -legacy 选项:

1
2
3
4
5
6
openssl pkcs12 -export \
    -out server-legacy.p12 \
    -inkey server.key \
    -in server.crt \
    -legacy \
    -passout pass:changeit

⚠️ 注意:-legacy 选项会使用较旧的加密算法,可能降低安全性,仅在兼容旧系统时使用。


常用命令速查

用途 命令
创建 PKCS#12 openssl pkcs12 -export -out file.p12 -inkey key.pem -in cert.pem -passout pass:PASSWORD
查看内容 openssl pkcs12 -in file.p12 -info -noout -passin pass:PASSWORD
提取证书 openssl pkcs12 -in file.p12 -clcerts -nokeys -out cert.pem -passin pass:PASSWORD
提取私钥 openssl pkcs12 -in file.p12 -nocerts -out key.pem -passin pass:PASSWORD -passout pass:NEWPASSWORD
提取 CA openssl pkcs12 -in file.p12 -cacerts -nokeys -out ca.pem -passin pass:PASSWORD
导出不含私钥 openssl pkcs12 -in file.p12 -nokeys -out certs.pem -passin pass:PASSWORD

安全注意事项

1. 密码强度

  • 使用强密码,建议至少 12 位,包含大小写字母、数字和特殊字符
  • 不同环境使用不同密码,避免重复使用

2. 文件权限

PKCS#12 文件和提取的私钥应设置合适的文件权限:

1
2
chmod 600 server.p12
chmod 600 server-key.pem

3. 传输安全

  • 在网络上传输 PKCS#12 文件时使用加密通道(如 SCP、SFTP、HTTPS)
  • 避免通过邮件传输或使用不安全的 FTP

4. 及时清理

  • 不再需要的 PKCS#12 文件应及时删除
  • 临时文件和测试文件不要留在生产环境中

5. 备份策略

  • 妥善备份 PKCS#12 文件和密码
  • 建议将备份存储在安全的位置(如加密的存储)

常见问题

问题 1:无法导入到 Windows

如果 PKCS#12 文件无法导入到 Windows 系统,尝试使用 -legacy 选项重新创建。

问题 2:密码错误

确保使用 -passin-passout 时密码一致(或明确知道哪个密码对应哪个操作)。

问题 3:提取的私钥格式不对

提取私钥后,如果需要确保格式正确,可以使用以下命令验证:

1
openssl rsa -in server-key.pem -check -passin pass:newpassword

总结

PKCS#12 是证书和私钥打包的标准格式,在服务器部署、证书迁移等场景中广泛使用。掌握 openssl pkcs12 命令的各种选项,可以轻松完成:

  • 创建包含证书和私钥的 PKCS#12 文件
  • 添加证书链
  • 提取证书和私钥
  • 调整加密算法以平衡安全性和兼容性

在实际使用中,请始终注意密码安全和文件权限管理。


参考来源