【问题标题】:How to enable Long Term Validation (LTV) with pdfbox如何使用 pdfbox 启用长期验证 (LTV)
【发布时间】:2021-07-14 05:16:53
【问题描述】:

我使用 pdfbox 进行签名,但在 acrobat 阅读器中检查签名时结果:长期验证(LTV)未启用

这是我的源代码

@Override
public byte[] sign(InputStream content) throws IOException {
    try {
        CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
        X509Certificate cert = (X509Certificate) this.certificateChain[0];
        ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA256WithRSA").build(this.privateKey);
        gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().build()).build(sha1Signer, cert));
        gen.addCertificates(new JcaCertStore(Arrays.asList(this.certificateChain)));
        CMSProcessableInputStream msg = new CMSProcessableInputStream(content);
        CMSSignedData signedData = gen.generate(msg, false);

        //add timestamp if TSA is available
        TimeStampManager timeStampManager = new TimeStampManager();
        signedData = timeStampManager.addSignedTimeStamp(signedData, timeStampToken);
        return signedData.getEncoded();
    } catch (Exception e) {
        // Write log error sign to table Log in DB
        // TODO: 10/19/20  
        
        //throw new IOException cause a SignatureInterface
        throw new IOException(e);
    }
}

TimestampManager.addSignedTimeStamp

/**
 * Extend cms signed data with TimeStamp first or to all signers
 *
 * @param signedData Generated CMS signed data
 * @param timeStampToken TimeStampToken
 * @return CMSSignedData Extended CMS signed data
 * @throws IOException, TSPException
 */
public CMSSignedData addSignedTimeStamp(CMSSignedData signedData, TimeStampToken timeStampToken) throws IOException, TSPException {
    SignerInformationStore signerStore = signedData.getSignerInfos();
    List<SignerInformation> signersWithTimeStamp = new ArrayList<>();
   
    for (SignerInformation signer : signerStore.getSigners()) {
        // This adds a timestamp to every signer (into his unsigned attributes) in the signature.
        signersWithTimeStamp.add(signTimeStamp(signer, timeStampToken));
    }

    // new SignerInformationStore have to be created cause new SignerInformation instance
    // also SignerInformationStore have to be replaced in a signedData
    return CMSSignedData.replaceSigners(signedData, new SignerInformationStore(signersWithTimeStamp));
}

/**
 * Extend CMS Signer Information with the TimeStampToken into the unsigned Attributes.
 *
 * @param signer information about signer
 * @return information about SignerInformation
 * @throws IOException
 */
private SignerInformation signTimeStamp(SignerInformation signer, TimeStampToken timeStampToken) throws IOException, TSPException {
    AttributeTable unsignedAttributes = signer.getUnsignedAttributes();

    ASN1EncodableVector vector = new ASN1EncodableVector();
    if (unsignedAttributes != null) {
        vector = unsignedAttributes.toASN1EncodableVector();
    }

    byte[] token = timeStampToken.getEncoded();
    ASN1ObjectIdentifier oid = PKCSObjectIdentifiers.id_aa_signatureTimeStampToken;
    ASN1Encodable signatureTimeStamp = new Attribute(oid, new DERSet(ASN1Primitive.fromByteArray(token)));
    vector.add(signatureTimeStamp);
    Attributes signedAttributes = new Attributes(vector);

    // replace unsignedAttributes with the signed once
    return SignerInformation.replaceUnsignedAttributes(signer, new AttributeTable(signedAttributes));
}

我希望签名自动启用 LTV 与此相同

请帮助在我的源代码中使用 pdfbox 在签名中自动启用 LTV! 谢谢!

【问题讨论】:

  • 您是否尝试过源代码下载中的AddValidationInformation.java 示例?
  • 我试试 AddValidationInformation AddValidationInformation 验证 = new AddValidationInformation();文件 outFile = File.createTempFile("outPdf", ".pdf");验证.validateSignature(inFile, outFile);但有错误:没有找到证书的颁发者证书:'CN=AMANO-TSU-320,OU=Thales TSS ESN:D420-2845-7C98,OU=e-timing TSA,O=AMANO Corporation,L=Yokohama,ST= Kanagawa, C=JP', ie Cert 'CN=SECOM TimeStamping CA3, O="SECOM Trust Systems CO.,LTD.", C=JP' is missing in the chain 原因证书和时间戳不匹配,因为我购买的证书我从 amano 购买的 secom 和时间戳?
  • 这意味着您的 TSA 服务器没有返回整个链,并且证书没有告诉从哪里获取它。要么告诉您的 TSA 返回整个链,要么自己下载丢失的证书并在需要时添加它,即更改示例代码以便在需要时使用此证书。签名和时间戳不必来自同一供应商。
  • @ShahidGhafoor 请帮我解决这个问题。
  • timeStampToken 没有在 sign() 方法中声明

标签: java pdfbox signature


【解决方案1】:

更新: 我使用 pdf-example 版本 2.0.21 时的问题 然后我将版本 pdf-example 更新为 2.0.23 然后我的问题就解决了

【讨论】:

  • 你至少应该提到你使用AddValidationInformation。示例中没有“自动启用 LTV”。
  • @TilmanHausherr 能否请您指出 addValidtionInformation 的最新示例?我目前正在处理这个问题,我想我错过了一些关键的步骤!谢谢
猜你喜欢
  • 2016-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-05
  • 1970-01-01
相关资源
最近更新 更多