当前位置: 首页 > 知识库问答 >
问题:

pdfbox-文档自签名后已被更改或损坏

龙飞
2023-03-14

我正在使用PDFbox-1.8.8在PDF文件上做签名功能。

当我签署一份文件的时候

下面是我的代码:

public void signDetached(String inputFilePath, String outputFilePath, String signatureImagePath, Sign signProperties) {
    OutputStream outputStream = null;
    InputStream inputStream = null;
    PDDocument document = null;
    InputStream signImageStream = null;

    try {
        setTsaClient(null);
        document = PDDocument.load(inputFilePath);
        // create signature dictionary
        PDSignature signature = new PDSignature();
        signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
        signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
        signature.setName("VANDUC1102");
        signature.setLocation(null);
        String displayName = "Hello World, Document signed by VANDUC1102";
        String reason = reasonText+ " " + displayName;
        signature.setReason(reason);

        // the signing date, needed for valid signature
        signature.setSignDate(Calendar.getInstance());            
        int signatureInPage = signProperties.getPageNumber() + 1;
        signImageStream = new FileInputStream(new File(signatureImagePath));
        PDVisibleSignDesigner visibleSig = new PDVisibleSignDesigner(inputFilePath, signImageStream, signatureInPage);

        float xAxis = convertPixel2Point(signProperties.getX()) ;
        float yAxis = convertPixel2Point(signProperties.getY());               
        float signImageHeight = convertPixel2Point(signImageHeight);    
        float signImageWidth = convertPixel2Point(signImageWidth);

        visibleSig.xAxis(xAxis)
                .yAxis(yAxis)
                .zoom(0)
                .signatureFieldName("Signature")
                .height(signImageHeight)
                .width(signImageWidth);
        PDVisibleSigProperties signatureProperties = new PDVisibleSigProperties();

        signatureProperties.signerName(eiUser.getName())
                 .signerLocation(null)
                 .signatureReason(reason)
                 .preferredSize(0)
                 .page(signProperties.getPageNumber())
                 .visualSignEnabled(true)
                 .setPdVisibleSignature(visibleSig)
                 .buildSignature();
         // register signature dictionary and sign interface
        SignatureOptions signatureOptions = new SignatureOptions();
        signatureOptions.setVisualSignature(signatureProperties);
        signatureOptions.setPage(signatureInPage);
        document.addSignature(signature, this, signatureOptions);

        File outputFile = new File(outputFilePath);
        outputStream = new FileOutputStream(outputFile);
        inputStream = new FileInputStream(inputFilePath);
        IOUtils.copyStream(inputStream, outputStream);
        document.saveIncremental(inputStream, outputStream);
        outputStream.flush();
    } catch (COSVisitorException | SignatureException | IOException ex) {
        log.error("signDetached ", ex);
    } finally {
        IOUtils.closeStream(outputStream);
        IOUtils.closeStream(inputStream);
        IOUtils.closeStream(signImageStream);
        IOUtils.closeStream(document);
    }
}
private float convertPixel2Point(float pixel){
    return pixel * (float) 72/96;
}

共有1个答案

袁泰平
2023-03-14

我刚看了你的pdf样本。从结构上看,它看起来还可以,只是签名中给出的数据哈希值

e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

与带符号字节范围的实际哈希值不匹配

4f48eab20d340957bd5693104af097ed7363bd84181a6a1c834c138c1376cbe3

因此,要么文件确实在事后被操纵,要么签名过程中的哈希计算已经出了问题。

File outputFile = new File(outputFilePath);
outputStream = new FileOutputStream(outputFile);
inputStream = new FileInputStream(inputFilePath);
IOUtils.copyStream(inputStream, outputStream);
document.saveIncremental(inputStream, outputStream);
  • 已在前面的IOutils.CopyStream调用过程中读取,并且
  • 毕竟是错误的:它只引用原始PDF,但saveincrement需要一个inputstream引用带有原始PDF和新签名的PDF。

因此,可以这样修复:

File outputFile = new File(outputFilePath);
outputStream = new FileOutputStream(outputFile);
inputStream = new FileInputStream(inputFilePath);
IOUtils.copyStream(inputStream, outputStream);
IOUtils.closeStream(inputStream);
inputStream = new FileInputStream(outputFile);
document.saveIncremental(inputStream, outputStream);

(另请参见SignLikeVanduc1102测试方法TestCorportFixed。)

File outputDocument = new File(document.getParent(), substring + "_signed.pdf");
FileInputStream fis = new FileInputStream(document);
FileOutputStream fos = new FileOutputStream(outputDocument);

int c;
while ((c = fis.read(buffer)) != -1) {
  fos.write(buffer, 0, c);
}
fis.close();
fis = new FileInputStream(outputDocument); 
 类似资料:
  • 对于一个关于签名数据被哈希两次的C#问题,我看到了一个类似的答复,但是我不知道为什么我的签名数据会出现在这里。 C#PKCS7 Smartchard数字签名损坏

  • 我试图对pdf文件进行签名,但在Adobe中打开签名的pdf文件时,遇到“文档自签名后已被更改或损坏”错误。 这个错误不是那么描述性的,我不确定应该在哪里查看,因为代码对我来说似乎很好,但显然不是。。 我使用的代码是: 签名的哈希的Base64格式为(tmp文件sha_前缀): 签名(AMA)的Base64格式为: 有人能帮忙吗?

  • 我正在按代码创建一个签名PDF,但由于某种原因,我收到此错误: 至少一个签名无效-文档签名后已被更改或损坏 我将DSS属性与VRI、Certs和CRL一起使用。重要的一点是,我使用的版本与我在讨论此过程的其他文章中看到的版本相同。所以我有第一部分的签名(内容<>和byterange[])和第二部分与他的孩子的DSS。我注意到,如果删除第二个生成的部分,Adobe Acrobat将给出: 已签名且所

  • 我尝试使用智能卡(USB令牌)对pdf文件进行签名,但在Adobe中打开签名的pdf文件时,遇到错误。这个错误不是描述性的,我也不知道该去哪里看,因为代码对我来说似乎很好,但显然不是… 我使用的代码是: 我尝试签名的pdf文件是这个。 添加签名字段后创建的临时pdf文件如下。 签名的Base64格式为

  • 我正在为我的应用程序做一个PDF签名功能。以下是工作流程: PDF存储在服务器上。 我将所有必需的签名字段包含到文件中,并使用ZendPDF的扩展名为FaritPDF计算字节长度等。 我根据使用SHA256计算的字节长度计算哈希。 哈希将发送到客户端。 客户端使用PFX文件对哈希进行签名,并创建包含哈希的PKCS7对象。 将PKCS7对象发送到服务器。 PKCS7对象包含在PDF中,并呈现PDF。