不导出私钥,从 P12 中取出证书
PKCS12 包把密钥和证书放在一起。先读结构,再用 -nokeys 选择证书,而不是剥离保护。
支持工单问的是 VPN 包里究竟是哪张证书,而第一反应往往是把所有东西导出再附上。P12 文件把证书和私钥材料装进同一个容器,所以全部导出恰恰是你最不该发送的东西。回答这个问题的命令是选择问题,不是转换问题。四个开关决定你拿到容器的哪一半,其中两个听起来比实际更安全。
先从读取容器开始,而不是把它清空。
PKCS12 文件到底装了什么
PKCS12 容器装有一张或多张证书、可能还有一把私钥,以及覆盖内容的消息认证码。证书里可能包括客户端身份的叶子证书,以及把它链到 CA 的中间证书。私钥一旦存在,正是它让文件成为秘密而不是文档。
这个区别正是 -nokeys 存在的原因,也正是这项任务需要这个开关的原因。
读取包,但不把私钥写出来
检查形式 打印结构和算法细节,什么也不写: openssl pkcs12 -in client.p12 -info -noout。它会询问导入密码,这个值放在这里才对;它还会告诉你文件里到底有没有私钥。无法手动输入密码时用 -passin env:PKCS12_PASS,因为写在 shell 命令里的密码就是进程列表里的密码。这一步不导出任何东西,而这正是要点。
从输出里读三件事:证书有几张、有没有私钥、哪些算法在保护它。
用 -nokeys,别把它和 -nocerts 弄混
-nokeys 排除私钥,留下证书。-clcerts 把范围收窄到客户端证书,-cacerts 收窄到 CA 证书,这两个是筛选器,不是替代品。-nocerts 读起来像是同一个想法的安全拼法,意思却相反:没有证书,只剩私钥。把它混进证书导出,正是私钥落到磁盘上的方式。
只生成证书文件和 CA 文件、不生成别的东西的两行写法是:
openssl pkcs12 -in client.p12 -nokeys -clcerts -out client-certificates.pem
openssl pkcs12 -in client.p12 -nokeys -cacerts -out ca-certificates.pem旧包的加密算法较老,在 OpenSSL 3 上需要 -legacy 才能读;这个开关改变的是解析器接受什么,而不是它输出什么。如果解析因不支持的算法报错,加上 -legacy 才是正确的第一步,跳过 MAC 校验则不是。
看输出,不要只看退出码
退出状态为零只说明命令跑过,不说明文件里有你期待的内容。数一数输出里的证书,读一读 subject 和日期:openssl x509 -in client-certificates.pem -noout -subject -dates -fingerprint。把指纹和支持团队期待的值比对,因为含两张客户端证书的包会生成两个块,而多数工具只读第一个。用途、信任和密钥匹配又是另外的检查。
能解析的证书就是能解析的证书。它不是 VPN 会接受的证书。
决定是否真的需要文件
如果接收方客户端直接导入 PKCS12,那么把原始包通过获批渠道发送、并把密码单独保管更简单,也保住了保护。提取是为了检查、为了需要 PEM 的客户端,或者为了要求特定产物的支持案例。每次提取都去掉一层,都该有理由。
公开证书不含私钥,但含姓名和组织信息。除非要的就是文件本身,否则请分享工单要求的字段,而不是文件。