You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js不调用外部OpenSSL能否实现原生数据签名

能否在Node.js中实现原生CMS签名替代OpenSSL命令

可以实现,不需要调用外部OpenSSL进程,以下是符合你给出命令要求的实现方案。

你给出的目标命令拆解后需要满足的核心能力:

  • 生成CMS签名结构,签名不分离(原始内容嵌入结果)
  • 二进制处理输入内容,输出DER格式结果
  • 摘要算法使用SHA256
  • 结果支持DES加密

实现方案

方案1:纯JS实现(无系统依赖,兼容低版本Node.js)

使用纯JS编写的加密工具库node-forge完成全部逻辑,不需要依赖本地安装的OpenSSL。

  • 先安装依赖:npm install node-forge
  • 示例代码:
const forge = require('node-forge');
const fs = require('fs');

// 替换为你的实际文件路径
const certPem = fs.readFileSync('./signer.crt', 'utf8');
const privateKeyPem = fs.readFileSync('./private.key', 'utf8');
const rawContent = fs.readFileSync('./input_content');

// 解析证书和私钥
const signerCert = forge.pki.certificateFromPem(certPem);
const signerKey = forge.pki.privateKeyFromPem(privateKeyPem);

// 初始化PKCS7(CMS)签名对象
const p7 = forge.pkcs7.createSignedData();
// 嵌入原始内容,*对应-nodetach、-binary参数*
p7.content = forge.util.createBuffer(rawContent);
// 配置签名者信息,指定SHA256摘要算法
p7.addSigner({
  key: signerKey,
  certificate: signerCert,
  digestAlgorithm: forge.pki.oids.sha256,
  authenticatedAttributes: [
    { type: forge.pki.oids.contentType, value: forge.pki.oids.data },
    { type: forge.pki.oids.messageDigest },
    { type: forge.pki.oids.signingTime }
  ]
});
p7.addCertificate(signerCert);
// 执行签名
p7.sign();
// 转换为DER格式输出,*对应-outform DER参数*
const derSignature = forge.asn1.toDer(p7.toAsn1()).getBytes();

// DES加密签名结果,*对应-des参数*
const desKey = forge.random.getBytesSync(8);
const desIv = forge.random.getBytesSync(8);
const desCipher = forge.cipher.createCipher('DES-CBC', desKey);
desCipher.start({ iv: desIv });
desCipher.update(forge.util.createBuffer(derSignature));
desCipher.finish();
const encryptedResult = desCipher.output.getBytes();

// 写入结果文件
fs.writeFileSync('./output_signed.der', Buffer.from(encryptedResult, 'binary'));

方案2:Node.js原生模块实现(Node.js >= 16.0.0)

Node.js 16及以上版本内置的crypto模块已支持CMS签名能力,不需要安装第三方依赖:

const { createSign, createCipheriv, randomBytes } = require('crypto');
const fs = require('fs');

// 替换为你的实际文件路径
const signerCert = fs.readFileSync('./signer.crt');
const signerKey = fs.readFileSync('./private.key');
const rawContent = fs.readFileSync('./input_content');

// 生成CMS签名
const sign = createSign('SHA256');
sign.update(rawContent);
sign.end();
const derSignature = sign.sign({
  key: signerKey,
  cert: signerCert,
  type: 'cms',
  format: 'der',
  detached: false // *对应-nodetach参数*
});

// DES加密签名结果,*对应-des参数*
const desKey = randomBytes(8);
const desIv = randomBytes(8);
const desCipher = createCipheriv('des-cbc', desKey, desIv);
const encryptedResult = Buffer.concat([desCipher.update(derSignature), desCipher.final()]);

// 写入结果文件
fs.writeFileSync('./output_signed.der', encryptedResult);

结果验证

生成的签名文件可以直接用OpenSSL命令验证有效性:

openssl cms -verify -in ./output_signed.der -inform DER -CAfile ./root_ca.crt

内容的提问来源于stack exchange,提问作者New Leepanyaporn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 04:57:03