无法将ltv添加到PDF文档。错误 [英] Can't add ltv to PDF document. Error

查看:220
本文介绍了无法将ltv添加到PDF文档。错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是使用Itext的签名文件。我有这个方法:

  public static void sign(String src,String dest,Certificate [] chain,PrivateKey pk,String digestAlgorithm ,String provider,CryptoStandard subfilter,TSAClient tsa)
{

//创建阅读器和压模
PdfReader reader = new PdfReader(src);
FileOutputStream os = new FileOutputStream(dest);
PdfStamper stamper = PdfStamper.createSignature(reader,os,'\ 0');

//创建外观
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setVisibleSignature(new Rectangle(10,20,100,200),1,sig);

//创建签名
ExternalDigest digest = new BouncyCastleDigest();
ExternalSignature signature = new PrivateKeySignature(pk,
digestAlgorithm,provider);
MakeSignature.signDetached(外观,摘要,签名,链,null,null,tsa,0,subfilter);


// ALENDADY SIGNED。立即加入LTB。
CrlClient crlClient = new CrlClientOnline(http://crl.mycrl.com/mycrl.crl);
OcspClient ocspClient = new OcspClientBouncyCastle();
addLtv(DEST,DEST2,ocspClient,crlClient,tsa);

}

我签了:

  sign(SRC,String.format(DEST,1),chain,pk,DigestAlgorithms.SHA256,provider.getName(),CryptoStandard.CMS,For Testing ,location,tsa); 

一切有效。 PDF 签名好



但是,我无法添加ltv。我使用来自itext文档的代码:

  public static void addLtv(String src,String dest,OcspClient ocsp,CrlClient crl,
TSAClient tsa)抛出IOException,DocumentException,
GeneralSecurityException {

PdfReader r = new PdfReader(src);
FileOutputStream fos = new FileOutputStream(dest);

PdfStamper stp = PdfStamper.createSignature(r,fos,'\ 0',null,true);
LtvVerification v = stp.getLtvVerification();

AcroFields fields = stp.getAcroFields();

List< String> names = fields.getSignatureNames();
String sigName = names.get(names.size() - 1);

PdfPKCS7 pkcs7 = fields.verifySignature(sigName);

if(pkcs7.isTsp()){
v.addVerification(sigName,ocsp,crl,
LtvVerification.CertificateOption.SIGNING_CERTIFICATE,
LtvVerification.Level.OCSP_CRL ,
LtvVerification.CertificateInclusion.NO);
}

else {
for(String name:names){
v.addVerification(name,ocsp,crl,
LtvVerification.CertificateOption.WHOLE_CHAIN ,
LtvVerification.Level.OCSP_CRL,
LtvVerification.CertificateInclusion.NO);
}
}
PdfSignatureAppearance sap = stp.getSignatureAppearance();
LtvTimestamp.timestamp(sap,tsa,null);
}

编辑:
一切正常,但在$行b $ b LtvTimestamp.timestamp(sap,tsa,null);
我有这个错误:
线程main中的异常java.io.IOException:没有足够的空间



这是我的pdf :
,Adobe文档 PDF中的数字签名(我从中复制了上图),PDF规范ISO 32000-1:2008可用< a href =http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/PDF32000_2008.pdf =nofollow noreferrer>这里是Adobe 。


I'm sign document, using Itext. I have that method:

public static void sign(String src, String dest, Certificate[] chain,PrivateKey pk, String digestAlgorithm, String provider,CryptoStandard subfilter, TSAClient tsa )
{

        // Creating the reader and the stamper
        PdfReader reader = new PdfReader(src);
        FileOutputStream os = new FileOutputStream(dest);
        PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');

        // Creating the appearance
        PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
        appearance.setVisibleSignature(new Rectangle(10, 20, 100, 200), 1, "sig");

        // Creating the signature
        ExternalDigest digest = new BouncyCastleDigest();
        ExternalSignature signature = new PrivateKeySignature(pk,
        digestAlgorithm, provider);
        MakeSignature.signDetached(appearance, digest, signature, chain, null,null, tsa, 0, subfilter);


        // ALREADY SIGNED. ADD LTB NOW.
        CrlClient crlClient = new CrlClientOnline("http://crl.mycrl.com/mycrl.crl");
        OcspClient  ocspClient=new OcspClientBouncyCastle();              
    addLtv(DEST, DEST2, ocspClient, crlClient, tsa);

    }

and I sign:

sign(SRC, String.format(DEST, 1), chain, pk, DigestAlgorithms.SHA256, provider.getName(), CryptoStandard.CMS, "For Testing", " location", tsa);

everything works. PDF is signed well.

but then, I can't add ltv. I use code from itext documentation:

public static void addLtv(String src, String dest, OcspClient ocsp, CrlClient crl,
        TSAClient tsa) throws IOException, DocumentException,
        GeneralSecurityException {

    PdfReader r = new PdfReader(src);
    FileOutputStream fos = new FileOutputStream(dest);

    PdfStamper stp = PdfStamper.createSignature(r, fos, '\0', null, true);
    LtvVerification v = stp.getLtvVerification();

    AcroFields fields = stp.getAcroFields();

    List<String> names = fields.getSignatureNames();
    String sigName = names.get(names.size() - 1);

    PdfPKCS7 pkcs7 = fields.verifySignature(sigName);

    if (pkcs7.isTsp()) {
            v.addVerification(sigName, ocsp, crl,
                LtvVerification.CertificateOption.SIGNING_CERTIFICATE,
                LtvVerification.Level.OCSP_CRL,
                LtvVerification.CertificateInclusion.NO);
    }

    else {
        for (String name : names) {
            v.addVerification(name, ocsp, crl,
                    LtvVerification.CertificateOption.WHOLE_CHAIN,
                    LtvVerification.Level.OCSP_CRL,
                    LtvVerification.CertificateInclusion.NO);
        }
    }
    PdfSignatureAppearance sap = stp.getSignatureAppearance();
    LtvTimestamp.timestamp(sap, tsa, null);
}

EDITED: everything works, but at line LtvTimestamp.timestamp(sap, tsa, null); I have that error: Exception in thread "main" java.io.IOException: Not enough space

that's my pdf: https://www.dropbox.com/s/o05rw6ubiuslm4j/DOC_SIGNED.pdf

Exception in thread "main" java.io.IOException: Not enough space
at com.itextpdf.text.pdf.security.LtvTimestamp.timestamp(LtvTimestamp.java:103)
at ge.digital.signature.DocumentSigner.DigitalSignature.addLtv(MySignature.java:132)
at ge.digital.signature.DocumentSigner.DigitalSignature.main(MySignature.java:163)

解决方案

That IOException occurs when the space reserved in the PDF for the integration of the time stamp does not suffice. Thus, you have to change the method getTokenSizeEstimate of the TSAClient instance tsa you call your sign method with to return a larger estimate of the time stamp size.

In case of the TSAClientBouncyCastle implementation of TSAClient, e.g., you can make it return arbitrary estimates instead of the default 4096 if you use the constructor with four arguments:

public TSAClientBouncyCastle(String url, String username, String password, int tokSzEstimate)

Some background: When integrating a signature or a document time stamp into a PDF, you first prepare the PDF with a gap of a given size, then calculate the hash of everything but that gap, then sign or time stamp that hash, and finally integrate the generated signature or time stamp into that gap, e.g.

(That /ByteRange entry is part of the signed content. Thus, one cannot enlarge the gap afterwards.)

Therefore, you have to use some estimate of the size of the generated signature or time stamp before its generation.

In case of document time stamps, this estimate is provided by the TSAClient method getTokenSizeEstimate.

PS: For still more details cf. this answer, the Adobe document Digital Signatures in a PDF (from which I copied the figure above), and the PDF specification ISO 32000-1:2008 made available here by Adobe.

这篇关于无法将ltv添加到PDF文档。错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆