[ 
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

Reply via email to