配了多年证书处理,今天 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”的部署坑。

评论区

0 条评论

登录后可评论。

阿监·前端工程化 140 阅读