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

Node.js下用Diia的PFX证书签PDF失败:不支持MAC算法1.2.804.2.1.1.1.1.2.1

解决Diia PFX证书签名PDF的MAC算法不支持问题及.dat文件使用指南

一、解决MAC算法不支持报错

报错Error: PKCS#12 uses unsupported MAC algorithm: 1.2.804.2.1.1.1.1.2.1是因为你的PFX证书使用了乌克兰GOST标准的MAC算法,当前signpdf依赖的加密库不支持该算法,可通过以下两种方案解决:

方案1:用OpenSSL转换证书格式

通过OpenSSL重新导出PFX证书,指定通用支持的MAC算法(如SHA256):

  1. 将原PFX转换为PEM格式:
openssl pkcs12 -in original.pfx -out temp.pem -nodes
  1. 重新打包为PFX并指定SHA256作为MAC算法:
openssl pkcs12 -export -in temp.pem -out new.pfx -macalg sha256

之后用转换后的new.pfx替换代码中获取到的signer.asset.certFile即可。

方案2:替换加密库支持GOST算法

如果无法转换证书,可以使用支持GOST算法的Node.js库(如node-gost)自定义签名逻辑,替换signpdf默认的P12Signer。这种方式需要修改签名实现,复杂度较高,适合有加密开发经验的场景。

二、.dat文件的使用

Diia提供的.dat文件是根/中间证书链文件,用于验证签名合法性,需将其加入PDF签名的证书链中:

  1. 读取.dat文件并解析证书:
const fs = require('fs');
const { Certificate } = require('@fidm/x509');

// 读取dat文件(替换为你的文件路径,或从配置/存储中获取)
const datCertBuffer = fs.readFileSync('./diia_ca.dat');
// 解析为证书原始数据
const caCert = Certificate.fromPEM(datCertBuffer).raw;
  1. 在签名时传入证书链:
    修改签名代码,添加certificateChain参数:
const signed = await signpdf.sign(pdfToSign, signer, {
  certificateChain: [caCert],
});

三、整合后的代码示例

const assetAccessCode = await this.configFacade.get(SIGN_CERTIFICATE_ASSET_ACCESS_CODE);
const assetId = await this.configFacade.get(SIGN_CERTIFICATE_ASSET_ID);
const fs = require('fs');
const { Certificate } = require('@fidm/x509');

let signerAsset = await send(this.secureStorage, 'assetGet', { assetAccessCode, assetId, clientId }).catch((error) => {
  this.logger.error(`Secure Storage request:${JSON.stringify({ assetAccessCode, assetId, clientId })}`);
  this.logger.error(`Secure Storage unavailable:${JSON.stringify(error)}`);
  throw Error(error);
});

// 使用转换后的PFX证书内容
const convertedPfxBuffer = Buffer.from(signerAsset.asset.certFile);

const pdfToSign = plainAddPlaceholder({
  pdfBuffer,
  reason: ' ',
  contactInfo: ' ',
  name: ' ',
  location: 'UK',
});

const signer = new P12Signer(convertedPfxBuffer, {
  passphrase: signerAsset.asset.password,
  asn1StrictParsing: true,
});

// 加载并解析.dat证书链
const datCertBuffer = fs.readFileSync('./diia_ca.dat');
const caCert = Certificate.fromPEM(datCertBuffer).raw;

const signed = await signpdf.sign(pdfToSign, signer, {
  certificateChain: [caCert],
});
return signed;

内容的提问来源于stack exchange,提问作者Анна Верба

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 02:25:17