配了多年证书处理,今天 Node.js 把 PKCS#12 解析做进了标准库——.p12 文件直接读,再不用调 OpenSSL 命令行了
做过后端服务的工程师都踩过这个坑:用户上传了一个 .p12(或 .pfx)证书文件,程序需要读取里面的私钥和证书来建立 TLS 连接。
过去,这件事 Node.js 自己做得到——TLS 握手时浏览器会自动解析 PKCS#12 文件——但应用层拿不到。你要么装一个第三方库(如 pkcs12js),要么在构建脚本里调 OpenSSL 命令行把内容导出来:
# 以前:需要 OpenSSL 把 p12 转换成 PEM
openssl pkcs12 -in your cert.p12 -nodes -out cert.pem
openssl pkcs12 -in your cert.p12 -nocerts -out key.pem
# 然后在代码里读这两个文件
Node.js 26.10.0(2026-09-21 发布)把这件事做进了 crypto 标准模块:crypto.parsePKCS12(),一个函数直接把二进制数据变成你需要的对象。
做了什么
crypto.parsePKCS12(buffer, password) 接受一个 ArrayBuffer(或 Buffer)和密码字符串,返回:
import { parsePKCS12 } from 'node:crypto';
const p12Data = fs.readFileSync('your-cert.p12');
const { privateKey, certificate, ca } = parsePKCS12(p12Data, 'your-password');
// privateKey — 私钥(PEM 格式字符串)
// certificate — X.509 证书(PEM 格式字符串)
// ca — 其他证书数组(可选,用于信任链)
这个对象里的数据格式和 Node.js TLS 模块内部使用的一致,所以可以直接传给 tls.createSecureContext():
import { parsePKCS12 } from 'node:crypto';
import { readFileSync } from 'node:fs';
import { connect } from 'node:tls';
const p12 = readFileSync('client.p12');
const { privateKey, certificate, ca } = parsePKCS12(p12, process.env.P12_PASSWORD);
const socket = connect(443, 'example.com', {
key: privateKey,
cert: certificate,
ca: ca,
});
之前用 OpenSSL 导出的方案要维护两个文件(.pem + key.pem),还要在部署时确保构建脚本能调用系统级 OpenSSL,在容器化环境里特别容易因为镜像里没有 OpenSSL 而失败。现在一个 readFileSync 加一次函数调用,全在进程内完成,零外部依赖。
三个具体场景
场景一:Web 服务接受用户上传的客户端证书
企业内网系统常需要双向 TLS(mTLS):客户端出示证书证明身份。用户的证书往往以 .p12 格式导出,服务器需要读取私钥和证书链来验证签名。过去需要先把 p12 转成 PEM,再手动拼接信任链;现在直接解析,一次拿到全部字段。
场景二:Electron 应用访问系统密钥库
Electron 应用需要用客户端证书访问企业内部 API。在 macOS 上,证书通常存放在 Keychain 里并以 p12 形式导出;用 node:crypto 直接解析,避免了调用系统级 security 命令行工具或引入原生模块。
场景三:CLI 工具验证 TLS 配置
运维工程师写一个检查证书有效期的脚本,以前要处理 p12 → pem 两步,现在几行脚本直接读取并检查 certificate 对象的有效期:
import { parsePKCS12 } from 'node:crypto';
import { readFileSync } from 'node:fs';
import { parseDER } from 'node:crypto';
const p12 = readFileSync('cert.p12');
const { certificate } = parsePKCS12(p12, process.env.P12_PASSWORD);
// 从 PEM 格式证书中提取有效期(简化示例)
浏览器支持与降级
Node.js 26.10 从 2026 年 9 月 21 日起随 Node.js 26 LTS 进入稳定版。如果你的 Node 版本低于 26.10,可以继续用第三方库(pkcs12js、node-forge)或上述 OpenSSL 导出的方案做渐进增强。parsePKCS12 属于 node:crypto 模块,不需要 --experimental 开关。
三步接入
第一步:升级 Node.js(如果还没到 26.10)
nvm install 26.10.0
nvm use 26.10.0
第二步:替换你的 p12 读取代码
把构建脚本里的 openssl pkcs12 命令行调用,替换成 crypto.parsePKCS12():
// 旧代码(构建时调 OpenSSL)
// exec('openssl pkcs12 -in cert.p12 -nocerts -out key.pem')
// 新代码(运行时直接读)
import { parsePKCS12 } from 'node:crypto';
const p12 = readFileSync('client.p12');
const { privateKey, certificate } = parsePKCS12(p12, password);
第三步:更新部署配置
之前依赖系统 OpenSSL 的容器镜像可以把 OpenSSL 依赖移除,减小镜像体积,同时避免”生产服务器上没有 OpenSSL”的部署坑。
评论区
登录后可评论。