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

使用外部API签名PDF时提示文档已篡改的问题排查

解决PDF外部API签名后提示篡改的问题

核心问题排查

  • 确认哈希计算范围:PDF签名仅针对签名域定义的ByteRange内的字节计算哈希,而非整个文档。外部API接收的哈希必须是该范围的哈希值,且哈希算法(如SHA-256)要与PDF签名域指定的算法完全一致。
  • 检查签名后PDF完整性:签名完成后绝对不能修改PDF的任何内容(包括元数据、空白字符等),否则会触发篡改提示。

正确使用ExternalSigningSupport的示例(以iText 7为例)

// 初始化PDF签名器
PdfSigner signer = new PdfSigner(new PdfReader(inputPdf), new FileOutputStream(outputPdf), new StampingProperties().useAppendMode());

// 配置签名外观与算法
PdfSignatureAppearance appearance = signer.getSignatureAppearance();
appearance.setReason("Document signing");
appearance.setLocation("Location");
signer.setFieldName("Signature1");
signer.setDigestAlgorithm(DigestAlgorithms.SHA256);

// 获取外部签名支持对象,提取待签名字节流
ExternalSigningSupport externalSigning = signer.getExternalSigningSupport();
byte[] bytesToSign = IOUtils.toByteArray(externalSigning.getContent());

// 计算待签名哈希(若外部API要求直接传入字节流则跳过此步)
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hashToSign = digest.digest(bytesToSign);

// 调用外部API获取签名结果与证书链
byte[] signedHash = externalSignApi.signHash(hashToSign);
X509Certificate[] certificateChain = externalSignApi.getCertificateChain();

// 将签名与证书链写入PDF
externalSigning.setSignature(signedHash);
signer.signExternalContainer(externalSigning, certificateChain);

关键注意事项

  • 若外部API要求对哈希值二次哈希(部分CA有此要求),需严格匹配算法,避免重复计算导致哈希不匹配。
  • 证书链必须完整(从用户证书到根CA),且按正确顺序写入签名域。
  • 调试时可打印bytesToSign的哈希值,与外部API接收的哈希值对比,确保完全一致;用PDF阅读器查看签名属性,确认哈希算法、证书链是否正确加载。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 18:52:10