[ https://issues.apache.org/jira/browse/PDFBOX-4312?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
bal reopened PDFBOX-4312: ------------------------- I am signing pdf using external *pkcs 7* signature with pdfbox 1.8.9 in .net. I have set all signatureproperties.I have *converted the base64 encoded signature in pkcs7 format to byte array by casting the responsexml to object. The byte array size is 2911 and i am passing this byte array to sign method which is called through saveincremental method*.but when i open pdf it shows me signed by unknown . when i expand this it show me there are *errors in the formatting or information contained in the signature.* please find below my code what is wrong in code ?? thanks in advance. {code:java} protected void Page_Load(object sender, EventArgs e) { string elemString = ""; string pdfPath = @"D:\balasaheb\esign_file_demo\testing.pdf"; float xCo_ordinates = 150; float yCo_ordinates = 400; float signatureWidth = 250; float signatureHeight = 100; string nameToShowOnSignatureStamp = "Sushrut Sathe"; string locationToShowOnSignatureStamp = "Latur"; string reasonForSign = "Testing"; string pdfPassword = ""; string txn = ""; int log_err = 1; int stampingPage = 1; string pdfname = System.IO.Path.GetFileName(pdfPath); string pdfDirectory = System.IO.Path.GetDirectoryName(pdfPath); string pdf = System.IO.Path.GetFileNameWithoutExtension(pdfPath); string outputFinalPdfDir = pdfDirectory; //string responseXml = System.IO.File.ReadAllText(@"D:\balasaheb\esign_file_demo\testing_responseXML.txt"); string responseXml = System.IO.File.ReadAllText(@"D:\balasaheb\esign_file_demo\responsexml.txt"); // Response XML Digest //**************************************************************************************************** // string responseXml = Request["msg"].ToString(); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(responseXml); XmlNodeList elemList = xmlDoc.GetElementsByTagName("DocSignature"); XmlNodeList esignResp = xmlDoc.GetElementsByTagName("EsignResp"); //string responseDocText = "Responsexml.txt"; foreach (XmlElement elem in esignResp) // elemList) { // elemString = elem.InnerText; string respStr = elem.OuterXml; // using (StreamWriter sw = new StreamWriter(pdfDirectory + "\\" + responseDocText)) // { // sw.Write(responseXml); // sw.Close(); // } //} // signature to byte array conversion byte[] signatureByte = Convert.FromBase64String(elemString); //byte sigarr = Convert.ToByte(elemString); // byte[] bytes = Encoding.UTF8.GetBytes(elemString); // byte[] sigarr = integersToBytes(signatureByte); byte[] sigbyts = System.Text.Encoding.UTF8.GetBytes(elemString); //using java conversion method byte[] bytes = Base64.encode(elemString.getBytes()); byte[] name = Base64.encode(elemString.getBytes()); byte[] decodedString = elemString.getBytes("UTF-8"); string docStr = Convert.ToBase64String(signatureByte); // conversion ascii byte[] asciiBytes = Encoding.ASCII.GetBytes(docStr); //decode and convert to byte array byte[] docBytes = Convert.FromBase64String(elemString); //string DocStr = Encoding.UTF8.GetString(docBytes); //byte[] docbytes = Encoding.UTF8.GetBytes(DocStr); // string docSig = Convert.ToBase64String(docBytes); EsignResponse resp = new EsignResponse(); // resp.getClass(); XmlObjectConverter xmlobj = new XmlObjectConverter(); EsignResponse fg = (EsignResponse)xmlobj.XmlToObject(resp, responseXml); byte[] docsig = fg.Signatures.DocSignature.docBytes; // string str = System.Text.ASCIIEncoding.ASCII.GetString(docsig); //store sigbytes to dictionary docSigDict.Add("doc", docsig); java.io.File inPutPdf = new java.io.File(pdfPath); string inPutPdfName = inPutPdf.getName(); FileInputStream fis = new FileInputStream(inPutPdf); // byte[] byteArray = null; InputStream inputStream = new FileInputStream(inPutPdf); System.String inputStreamToString = inputStream.toString(); inputStream.close(); //java.io.File outPutPdf = new java.io.File(pdfDirectory + "\\" + pdf + "Signed_Final.pdf"); //FileOutputStream fos = new FileOutputStream(outPutPdf); //org.apache.pdfbox.io.IOUtils.copy(fis, fos); //fis.close(); PDDocument signedDoc = PDDocument.load(pdfDirectory + "\\" + "testing.pdf"); signedDoc.getDocument().getTrailer().removeItem(COSName.TYPE); int pages = signedDoc.getNumberOfPages(); string tickImagePath = @"D:\balasaheb\tick.jpg"; FileInputStream tickImageStream = new FileInputStream(tickImagePath); List<Long> documentIds = new List<Long>(); List<string> calTimeStamp = new List<string>(); BoundingBox box = new BoundingBox(); PDRectangle Rect = new PDRectangle(box); java.util.Calendar cal = java.util.GregorianCalendar.getInstance(); SimpleDateFormat sd = new SimpleDateFormat("yyyyMMdd_HHmmss"); string timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(java.util.Calendar.getInstance().getTime()); cal.setTime(sd.parse(timeStamp)); cal.add(java.util.Calendar.MINUTE, 15); System.Random random = new System.Random(); int mapId = 0; Long docid = new Long(mapId + random.Next(1000, 9980)); string docIdTxt = pdfDirectory + "\\DocumentId.txt"; using (var streamReader = new StreamReader(pdfDirectory + "\\" + "timeStamp.txt", Encoding.UTF8)) { timeStamp = streamReader.ReadToEnd(); } int id; using (TextReader reader = System.IO.File.OpenText(docIdTxt)) { id = int.Parse(reader.ReadLine()); } Hash hash1 = new Hash(); string outpdfpath = pdfDirectory + "\\" + pdf + ".pdf"; string pdfUnsignedHash = hash1.CalHash(outpdfpath); string unsignedHash = "pdfHash1.txt"; using (StreamWriter sw = new StreamWriter(pdfDirectory + "\\" + unsignedHash)) { sw.Write(pdfUnsignedHash); sw.Close(); } try { // create visible signature properties PDVisibleSigProperties signatureProperties = new PDVisibleSigProperties(); //represents a digital signature that can be attached to a document. org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature pdsignature = new org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature(); pdsignature.setFilter(org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature.FILTER_ADOBE_PPKLITE); pdsignature.setSubFilter(org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED); //create signature dictionary //pdsignature.setLocation(locationToShowOnSignatureStamp); //pdsignature.setReason(reasonForSign); //pdsignature.setSignDate(cal); //pdsignature.getLocation(); //pdsignature.getName(); signedDoc.setDocumentId(docid); calTimeStamp.Add(timeStamp); //build visible signature template to add in pdf PDVisibleSigBuilder signatureBuilder = new PDVisibleSigBuilder(); // create pdftemplate PDFTemplateCreator tempCreator = new PDFTemplateCreator(signatureBuilder); signatureBuilder.createAcroForm(signedDoc); //build visible signature design PDVisibleSignDesigner visibleSigDesign = new PDVisibleSignDesigner(signedDoc, tickImageStream, 1); visibleSigDesign.xAxis(xCo_ordinates); visibleSigDesign.yAxis(yCo_ordinates).zoom(10); visibleSigDesign.signatureFieldName("signature"); signatureProperties.signerName("name").signerLocation("location") .signatureReason("Security") //Sets the preferred signature size in bytes. .preferredSize(5).page(1) // set visual signature add or not .visualSignEnabled(true) //set visible signature config obj and returns visible sig properties .setPdVisibleSignature(visibleSigDesign) //start building of visible signature .buildSignature(); //create default signature options. SignatureOptions sigOptions = new SignatureOptions(); if (signatureProperties != null && signatureProperties.isVisualSignEnabled()) { sigOptions.setPage(signatureProperties.getPage()); //read visual signature from signature properties sigOptions.setVisualSignature(signatureProperties); //sigOptions.setVisualSignature(createVisualSignatureTemplate(signedDoc, stampingPage, tickImagePath, nameToShowOnSignatureStamp,locationToShowOnSignatureStamp // , reasonForSign)); // add signature to document signedDoc.addSignature(pdsignature, this, sigOptions); } else { signedDoc.addSignature(pdsignature, this); } } catch (System.Exception ex) { ex.Message.ToString(); } // Get the first page PDDocumentCatalog catalog = signedDoc.getDocumentCatalog(); int pageCount = 1; string hash2 = hash1.CalHash(outpdfpath); string hash2txt = "pdfhash2.txt"; using (StreamWriter sw = new StreamWriter(pdfDirectory + "\\" + hash2txt)) { sw.Write(hash2); sw.Close(); } try { //InputStream fis = new FileInputStream(pdfDirectory + "\\" + "testingField.pdf"); ////remove unwanted trailer entry in pdfdoc //byte[] inputBytes = IOUtils.toByteArray(fis); //PDDocument pdDocument = PDDocument.load(new ByteArrayInputStream(inputBytes)); //PDJpeg ximage = new PDJpeg(pdDocument, tickImageStream); //PDPage page = (PDPage)pdDocument.getDocumentCatalog().getAllPages().get(0); //PDPageContentStream contentStream = new PDPageContentStream(pdDocument, page, true, true); //contentStream.drawXObject(ximage, 50, 50, 356, 40); //contentStream.close(); ////Creates a new byte array output stream. //ByteArrayOutputStream os = new ByteArrayOutputStream(); //pdDocument.save(os); //os.flush(); // remove unwanted trailer from trailer dictionary and set cross reference same for incremental update //ByteArrayOutputStream baos = new ByteArrayOutputStream(); //signedDoc.save(baos); //baos.flush(); //signedDoc.close(); //byte[] inputBytes = baos.toByteArray(); //signedDoc = PDDocument.load(new ByteArrayInputStream(inputBytes)); //signedDoc.getDocument().getTrailer().removeItem(COSName.TYPE); PDPage page = new PDPage(); signedDoc.getDocumentCatalog().getCOSObject().setNeedToBeUpdate(true); signedDoc.getDocumentCatalog().getPages().getCOSObject().setNeedToBeUpdate(true); //page.getCOSObject().setNeedToBeUpdate(true); //page.getResources().getCOSObject().setNeedToBeUpdate(true); //page.getResources().getCOSDictionary().getDictionaryObject(COSName.XOBJECT).setNeedToBeUpdate(true); ////ximage.getCOSObject().setNeedToBeUpdate(true); Debug.WriteLine("calling saveincremental"); signedDoc.saveIncremental(pdfDirectory + "\\" + pdf + "Signed_Final.pdf"); signedDoc.close(); } catch (System.Exception ex) { ex.Message.ToString(); } } } private byte[] integersToBytes(byte[] signatureByte) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baos); for (int i = 0; i < signatureByte.Length; ++i) { dos.writeInt(signatureByte[i]); } return baos.toByteArray(); } private InputStream createVisualSignatureTemplate(PDDocument signedDoc, int stampingPage, string tickImagePath, string nameToShowOnSignatureStamp, string locationToShowOnSignatureStamp, string reasonForSign) { java.io.File imageFile = new java.io.File(tickImagePath); COSDictionary cosDict = new COSDictionary(); PDPage page = new PDPage(cosDict); signedDoc.addPage(page); List<PDSignatureField> acroFormFields = new List<PDSignatureField>(); try { // PDAcroForm acroForm = new PDAcroForm(signedDoc); signedDoc.getDocumentCatalog().setAcroForm(acroForm); PDSignatureField signatureField = new PDSignatureField(acroForm); PDAnnotationWidget widget = new PDAnnotationWidget(); acroForm.getCOSObject().setDirect(true); acroFormFields.Add(signatureField); PDStream pdstream = new PDStream(signedDoc); //PDFormXObject form = new PDFormXObject(pdstream); PDResources res = new PDResources(); PDFont font = PDType1Font.HELVETICA_BOLD; PDResources rest = new PDResources(); //form.setResources(rest); //form.setFormType(1); //PDRectangle bbox = new PDRectangle(rect.getWidth(), rect.getHeight()); //float height = bbox.getHeight(); // form.PDVisualSigBuilder.createAppearanceDictionary(); PDAppearanceDictionary appearanceDict = new PDAppearanceDictionary(); appearanceDict.getCOSObject().setDirect(true); RandomAccess random = null; COSStream str = new COSStream(cosDict, random); PDAppearanceStream appearanceStream = new PDAppearanceStream(str); appearanceDict.setNormalAppearance(appearanceStream); widget.setAppearance(appearanceDict); try { PDPage page1 = new PDPage(); PDPageContentStream contentStream = new PDPageContentStream(signedDoc, page1); //cs.setNonStrokingColor(java.awt.Color.black); contentStream.addRect(-5000, -5000, 2000, 2000); contentStream.fill(1); contentStream.saveGraphicsState(); PDJpeg tickjpg = new PDJpeg(pdstream); contentStream.drawImage(tickjpg, 0, 0); contentStream.restoreGraphicsState(); //show text PDFont font1 = PDType1Font.TIMES_ITALIC; float fontSize = 8; float leading = fontSize * 1.0f; contentStream.beginText(); contentStream.setFont(font, fontSize); ByteArrayOutputStream baos = new ByteArrayOutputStream(); signedDoc.save(baos); } catch (System.Exception e) { e.ToString(); } } catch (System.Exception ex) { ex.ToString(); } return null; } // public byte[] sign(InputStream @is) { InputStream ipstream = @is; byte[] pdf = null; try { FileOutputStream fos = new FileOutputStream(@"D:\balasaheb\esign_file_demo" + "\\" + "temp_Signed.pdf"); byte[] buffer = new byte[ipstream.available()]; fos.write(buffer); fos.flush(); fos.close(); ipstream.close(); pdf = docSigDict["doc"]; } catch (System.Exception e) { e.ToString(); } return pdf; } private string gethash(string newPdfPath) { java.nio.file.Path pdfPath = Paths.get(newPdfPath); byte[] pdfbytes = Files.readAllBytes(pdfPath); SHA256 sha256 = SHA256.Create(); byte[] hash = sha256.ComputeHash(pdfbytes); java.lang.StringBuilder sb = new java.lang.StringBuilder(); for (int i = 0; i < hash.Length; i++) { sb.append(hash[i].ToString("X2")); } return sb.ToString(); } {code} > byte array format to pass to sign method > ---------------------------------------- > > Key: PDFBOX-4312 > URL: https://issues.apache.org/jira/browse/PDFBOX-4312 > Project: PDFBox > Issue Type: Wish > Components: .NET, PDModel, Signing > Affects Versions: 1.8.9 > Reporter: bal > Priority: Critical > > Hi , > I want to sign pdf using signature in pkcs 7 format . I am converting pkcs 7 > signature to byte array using Convert.FromBase64String method in .net . I am > passing this byte array to sign method in signature interface which gets > called after calling saveincremental. My byte array is inserting proper but > the name of which signature is not shown when i open pdf. May be my byte > conversion may not proper or something else i am doing wrong. please let me > know. -- This message was sent by Atlassian JIRA (v7.6.3#76005) --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@pdfbox.apache.org For additional commands, e-mail: dev-h...@pdfbox.apache.org