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

Apache PDFBox外部签名异常:签名后PDF提示已篡改求助

PDF签名后提示篡改的排查方案

哈希值大小验证

你提供的哈希值LXl/LHCaxrf7lYlN8d8m7gDNp9DRqY+azvxCS/mB3uY=是Base64编码格式,解码后为32字节(256位),这是SHA-256哈希算法的标准输出长度,大小完全正常,哈希本身的尺寸不是问题所在。

关键缺失步骤排查

结合Apache PDFBox 3.0.0的签名流程,重点检查以下环节:

1. 待哈希内容范围是否正确

PDF签名的核心是对签名占位符插入后的待签文档字节流计算哈希,而非原始PDF文件。需确认代码中是否通过ExternalSigningSupport.getContent()获取正确的数据流:

  • 错误做法:直接读取原始PDF文件的字节数组计算哈希
  • 正确做法:调用ExternalSigningSupport.getContent()获取PDFBox准备好的待签流,读取该流计算哈希

2. 签名算法与签名字典配置匹配

确保外部签名算法与PDF签名字典的参数完全一致:

  • 若使用SHA256withRSA签名,需设置:
    • 签名字典/Filter为/Adobe.PPKLite
    • /SubFilter为/adbe.pkcs7.detached(分离式签名)
    • /DigestAlgorithm为/SHA256
  • 检查CreateSignature中配置签名字典的代码,是否遗漏或错误设置了上述参数

3. 签名值的编码与写入逻辑

外部服务返回的签名通常是DER编码的二进制数据,需确保传递给PDFBox的是原始二进制签名:

  • 避免将Base64编码的签名直接写入PDF,需先解码为字节数组
  • 检查ExternalSignature实现,是否正确将外部服务返回的签名转换为字节数组后传递

4. 文档增量更新是否正确

PDF签名必须通过增量更新保存,不能覆盖原始文档:

  • 确认代码中使用saveIncremental()方法保存签名后的文档,而非普通的save()方法
  • 增量更新会保留原始文档内容,仅追加签名数据,这是保证签名有效性的关键

5. 外部签名流程的正确性

模拟外部签名时,需严格遵循“哈希→签名”的流程:

  • 先对待签字节流计算哈希,再用私钥对哈希值进行签名
  • 错误示例:直接对待签字节流签名(而非哈希)
  • 正确实现参考:
    @Override
    public byte[] sign(byte[] content) throws IOException {
        try {
            MessageDigest digest = MessageDigest.getInstance(getHashAlgorithm());
            byte[] hash = digest.digest(content);
            Signature signature = Signature.getInstance(getSignatureAlgorithm());
            signature.initSign(privateKey);
            signature.update(hash);
            return signature.sign();
        } catch (Exception e) {
            throw new IOException(e);
        }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 10:43:10