簡體   English   中英

使用iText通過ExternalSiging服務進行PDF簽名,

[英]PDF Signing with ExternalSiging service using iText,

我有一個pdf文檔,需要進行數字簽名,並且簽名由外部服務提供。 啟動簽名之前,我沒有證書鏈。 我嘗試了以下代碼,但收到了SigDict / Contents非法數據消息。

創建文檔哈希並將其發布到外部服務以對其進行簽名的源

    InputStream data = null;
    DocumentSignStatus documentSignStatus = new DocumentSignStatus();
    int contentEstimated = 8192;

    PdfReader reader = new PdfReader(requestParams.getDocumentToBeSigned());
    try {
    reader.unethicalreading = true;

    int pdfPagenumber = 1;

    if((Integer)requestParams.getSignPageNo() == null || requestParams.getSignPageNo()==0  ){           
        //pdfPagenumber = 1; // Default signature on first page.
        pdfPagenumber = reader.getNumberOfPages(); // Sign on last page

    }else {
        pdfPagenumber = requestParams.getSignPageNo();
    }

    PdfSignatureAppearance appearance = null;
    ByteArrayOutputStream  os = null;

    os = new ByteArrayOutputStream ();
    PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0', null, true);

    Calendar cal = Calendar.getInstance();        
    appearance = stamper.getSignatureAppearance();        
    appearance.setSignDate(cal);
    appearance.setAcro6Layers(false);
    appearance.setReason("Test Signature");
    appearance.setLocation("India");               
    appearance.setImage(null);
    appearance.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED);

    Rectangle rect = requestParams.getRect();        
    appearance.setVisibleSignature(rect, pdfPagenumber, null);

    HashMap<PdfName, Integer> exc = new HashMap<PdfName, Integer>();
    exc.put(PdfName.CONTENTS, new Integer(contentEstimated * 2 + 2));
    PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
    dic.setReason(appearance.getReason()); 
    dic.setLocation(appearance.getLocation());
    dic.setContact(appearance.getContact());
    dic.setDate(new PdfDate(appearance.getSignDate()));
    appearance.setCryptoDictionary(dic);

    appearance.preClose(exc);

    data = appearance.getRangeStream();    

    MessageDigest messageDigest;
    String provider = null;
    String hashAlgorithm = DigestAlgorithms.SHA256;
    if (provider == null){
        messageDigest = MessageDigest.getInstance(hashAlgorithm);
    }else {
        messageDigest = MessageDigest.getInstance(hashAlgorithm,provider);
    }


    int read = 0;
    byte[] buff = new byte[contentEstimated];

    while ((read = data.read(buff, 0, contentEstimated)) > 0)
    {
        messageDigest.update(buff,0,read);                      
    }
    byte[] hashDigest = messageDigest.digest();

    byte[] documentHash = org.bouncycastle.util.encoders.Hex.encode(hashDigest);

    //eSign Start        
    String hashdocument = new String(documentHash, "UTF-8");        
    System.out.println("Document Hash :"+hashdocument);


    //Generate Sign Request XML for external source to sign the document hash                
    String eSignXmlStr = esignXML.generateEsignXML20(hashdocument,requestParams.getAadhaarNo());                
    String eSignSignedXML = myXMLSigner.signXML(eSignXmlStr, true);
    System.out.print("sign request xml: " + eSignSignedXML);
    // sign request xml generation complete


    documentSignStatus.setSignedXML(eSignSignedXML);        
    session.put("hashdocument", documentHash);
    session.put("appearance", appearance);
    session.put("baos", os);

    }catch(Exception e) {
        e.printStackTrace();
    }
    return documentSignStatus;

以下是將PKCS7響應附加到pdf的源,以完成簽名過程並獲取簽名的pdf。

    byte[] hashdocument = (byte[])session.get("hashdocument");
    PdfSignatureAppearance appearance =  (PdfSignatureAppearance)session.get("appearance");
    ByteArrayOutputStream os = (ByteArrayOutputStream)session.get("baos");

    //Get signed response xml
    InputStream x = request.getInputStream();
    String responseXML = IOUtils.toString(x, "UTF-8");
    System.out.print("REsponse:" + responseXML);

    //parse the xml and get pkcs7 data
    String pkcs7asString = getPKCS7DataFromDigitalSignatureResponse(responseXML);
    byte[] signedDocByte = org.bouncycastle.util.encoders.Base64.decode(pkcs7asString);

    //////////////////// ADD SIGNED BYTES/HASH TO PDF DOCUMENT.                 
    int contentEstimated = 8129;
    byte[] paddedSig = new byte[contentEstimated];                   
    System.arraycopy(signedDocByte, 0, paddedSig, 0, signedDocByte.length);
    PdfDictionary dic2 = new PdfDictionary();
    dic2.put(PdfName.CONTENTS, new PdfString(paddedSig).setHexWriting(true));
    try {
        appearance.close(dic2);
    } catch (DocumentException e) {
        e.printStackTrace();
    }                   
    try(OutputStream outputStream = new FileOutputStream("/SignTest2.0.pdf")) {
        os.writeTo(outputStream);
    }

    os.close();                                             

方法getPKCS7DataFromDigitalSignatureResponse(responseXML)用於解析外部服務響應,它以字符串形式返回PKCS7。 我試圖找出問題所在,但找不到根本原因。 任何人都可以幫助解決這個問題。 使用itext版本5.4.5或將簽名文檔復制為帶有簽名問題的PDF

我發現了問題的根本原因,我犯了一個小錯誤,由於未正確創建paddedSig,上述來源中的內容估計變量不正確。 上面的來源中顯示的值有誤。 int contentEstimated = 8129; 正確值為int contentEstimated = 8192; 其余代碼很好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM