3

PDF document needs to signed with national digital identity.
National digital identity WebService provide facility to sign document, in my project I have integrated same.

Requesting Esign services give response in PKCS7(CMS) format. I want to append same response in multiple locations, So i am creating multiple empty signature container post i receive Response from service.

I referred this article : Sign Pdf Using ITextSharp and XML Signature

But in given article we only one signing location is present but i have multiple signing locations.

I am using itext sharp Library. Using MakeSignature.SignDeferred Method to append signature at multiple locations but it is showing PDF invalid.

Please find below response XML which i received from Webservice:

<?xml version="1.0" encoding="UTF-8"?>
<EsignResp errCode="NA" errMsg="NA" resCode="259A52453BE95D3A1071193995E062E3EAD796AD" status="1" ts="2019-03-18T14:26:59" txn="UKC:eSign:2998:20190318142602814">
    <UserX509Certificate>--Usercerti in base64--</UserX509Certificate>
    <Signatures>
        <DocSignature error="" id="1" sigHashAlgorithm="SHA256">--Signature in base 64 in PKCS7(CMS)---</DocSignature>
    </Signatures>
    <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        <SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
            <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></CanonicalizationMethod>
            <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"></SignatureMethod>
            <Reference URI="">
                <Transforms>
                    <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></Transform>
                </Transforms>
                <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></DigestMethod>
                <DigestValue>MrOfovytOIp/8qlEkgamrcyhGTSGTN5aS1P+08Fbwfk=</DigestValue>
            </Reference>
        </SignedInfo>
        <SignatureValue>BBexJyk47YaTdoDgXaFRCtJq1Gc3KsZNt48/I8X4TgNJ6gh2NI9Y5Y9Tc7bozrK/QRy1VYPOWYq5r/YdunjMQLmJJicyeqeqe2eD+TJ8oecpjCbmhPnDK2VgaJ2h00sfsfdsflIe/toKwAmV4PTBA1a5wkz77hj+HTkWXMkPEIsBUnBirVpHxe2bYaa7jcIIpWtJmqvcSurKTOeyFRa+AFWfwWHB/EzHJlDmgiMXzrNauxJ4HpphNaRU+bO5JdyzJs/8Zx4i6qwSEybkuprL3GdO9C7zMPiC98CTfO2dfUrbZWy1pSvwEqlVXQIfrkp+m2JRbFgT8EEIGfXUS+AJBPRwhY1Xsww==</SignatureValue>
        <KeyInfo>
            <KeyValue>
                <RSAKeyValue>
                    <Modulus>0o9vohWZ3ztI9ea8D/zUEUBRq6c82BE7sFmr1hNMeuGSJQFf39ceesRtGUzlUYVWXcU23P8sVZ5419CHh7ApFzUXaLD72i/2d5FFI0n3iRlTQec9PEUHyrvOCVDpqBhbnrO/EHBqRluUQJTQUtMu5mhPNFV7IIJMTEAsUhCL9adZXXQK9NeK0foRr29Oq7VdEGfSeLzHIibpQmhNPh89oJXqu0cmbNSW4J4i2GmwHQpmsmHaSQcgh4mgVrykO64pAKXPreAPipDHQM1l/e5hilYlWfLHxhC5OdfdfdsbTCTcydQ218IVulFOFhdQt7xVV61TOmoTC2elhWbDqoLJBVU5mBfQ==</Modulus>
                    <Exponent>AQAB</Exponent>
                </RSAKeyValue>
            </KeyValue>
            <X509Data>
                <X509SubjectName>CN=D-Random detail</X509SubjectName>
                <X509Certificate>--public certificate of provider--- </X509Certificate>
            </X509Data>
        </KeyInfo>
    </Signature>
</EsignResp>

EDIT: As per latest communication, Web Service provide response for whatever hash is being provided from my end. They do not validate it. Hash is any 64 character string. Kindly let me know what are the possible ways by which i can use this to append PKCS7 signature on a PDF document.

Below Code for generating request :

if (System.IO.File.Exists(tempPdf))
System.IO.File.Delete(tempPdf);

using (PdfReader reader = new PdfReader(pdfReadServerPath))
{
    using (FileStream os = System.IO.File.OpenWrite(tempPdf))
    {
        PdfStamper stamper = PdfStamper.CreateSignature(reader, os, '\0',null,true);

        PdfSignatureAppearance appearance = stamper.SignatureAppearance;

        appearance.SetVisibleSignature(new Rectangle(15, 15, 100, 100), 1, "sign1");

        appearance.CertificationLevel = PdfSignatureAppearance.NOT_CERTIFIED;
         AllPagesSignatureContainer external = new AllPagesSignatureContainer(appearance);

        MakeSignature.SignExternalContainer(appearance, external, 8192);
        Stream data = appearance.GetRangeStream();

       Stream data = appearance.GetRangeStream();
        byte[] hash = ReadFully(data); //Convert stream to byte
        _signatureHash = hash;


    }
}
//create sha256 message digest
using (SHA256.Create())
{
    _signatureHash = SHA256.Create().ComputeHash(_signatureHash);
}
bool check = false;
string hexencodedDigest = null;
//create hex encoded sha256 message digest
hexencodedDigest = new BigInteger(1, _signatureHash).ToString(16);
hexencodedDigest = hexencodedDigest.ToUpper();
if (hexencodedDigest.Length == 64)
{
    **Send this hexencoded hash to webservice**
}

Below code for appending signature:

//DLL Call
eSign2_1_Request_Response req_resp = new eSign2_1_Request_Response();

//// Response XML Digest process
string resp_xml = Request.Form["msg"].ToString();//signature response XML;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(resp_xml);
XmlElement EsignResp = xmlDoc.DocumentElement;
if (EsignResp.Attributes != null && EsignResp.Attributes["status"].Value != "1")
{
    req_resp.WriteTextFileLog("errCode: " + EsignResp.Attributes["errCode"].Value + " & Error Message: " + EsignResp.Attributes["errMsg"].Value, "log", base_folder_path);
}
else
{
    req_resp.WriteTextFileLog(resp_xml, "xml", base_folder_path + "\\" + file_withoutExtn + "_responseXML.txt");
    //-------Continue to generate signed PDF by passing parameter to DLL

    XmlNodeList nodeList = xmlDoc.GetElementsByTagName("Signatures");

    string signature = nodeList[0].FirstChild.InnerText;

    string signedPdf = @"D:\POC Hosted\TryNSDL\TryNSDL\wwwroot\TempPath\signedPdf.pdf";
    string tempPdf = @"D:\POC Hosted\TryNSDL\TryNSDL\wwwroot\TempPath\tempPdf.pdf";
    using (PdfReader reader = new PdfReader(tempPdf))
    {

        using (FileStream os = System.IO.File.OpenWrite(signedPdf))
        {
            byte[] encodedSignature = Convert.FromBase64String(signature);

            IExternalSignatureContainer external = new MyExternalSignatureContainer(encodedSignature);

            MakeSignature.SignDeferred(reader, "sign1", os, external);
        }
    }
}

Code for Allsignature container:

public class AllPagesSignatureContainer : IExternalSignatureContainer
{
    public AllPagesSignatureContainer(PdfSignatureAppearance appearance)
    {
        this.appearance = appearance;

    }

    public void ModifySigningDictionary(PdfDictionary signDic)
    {
        signDic.Put(PdfName.FILTER, PdfName.ADOBE_PPKMS);
        signDic.Put(PdfName.SUBFILTER, PdfName.ADBE_PKCS7_DETACHED);

        PdfStamper stamper = appearance.Stamper;
        PdfReader reader = stamper.Reader;
        PdfDictionary xobject1 = new PdfDictionary();
        PdfDictionary xobject2 = new PdfDictionary();
        xobject1.Put(PdfName.N, appearance.GetAppearance().IndirectReference);
        xobject2.Put(PdfName.AP, xobject1);

        PdfIndirectReference PRef = stamper.Writer.PdfIndirectReference;
        PdfLiteral PRefLiteral = new PdfLiteral((PRef.Number + reader.NumberOfPages) + " 0 R");

        for (int i = 2; i < reader.NumberOfPages+1; i++)
        {
            var signatureField = PdfFormField.CreateSignature(stamper.Writer);

            signatureField.Put(PdfName.T, new PdfString("ClientSignature_" + i.ToString()));
            signatureField.Put(PdfName.V, PRefLiteral);
            signatureField.Put(PdfName.F, new PdfNumber("132"));
            signatureField.SetWidget(new Rectangle(15, 15, 100, 100), null);
            signatureField.Put(PdfName.SUBTYPE, PdfName.WIDGET);

            signatureField.Put(PdfName.AP, xobject1);
            signatureField.SetPage();
            Console.WriteLine(signatureField);

            stamper.AddAnnotation(signatureField, i);
        }
    }

    public byte[] Sign(Stream data)
    {
       return new byte[0];
    }

    PdfSignatureAppearance appearance;

}

I used append mode in create signature then signature doesn't come. Only empty signatures are visible in adobe reader : /Fileremoved/

If i try same without appendmode PdfStamper stamper = PdfStamper.CreateSignature(reader, os, '\0'); and PdfLiteral PRefLiteral = new PdfLiteral((PRef.Number + 1 + 2 * (reader.NumberOfPages - 1)) + " 0 R"); then it works fine : /Fileremoved/, but it can be used for single signer only. Nd if we again try to use same pdf to Resign then old signatures becomes invalid. (obviously since append mode is not used.)

I guess For signing to work in append mode, Change is required in line of PdfLiteral - I have less idea about same how it actually works.

Signed file :/Fileremoved/ Input file: /Fileremoved/

  • Only only location is supported by the PDF format. You can have multiple appearances but Acrobat will fail the verification. So, one location and one appearance. – Paulo Soares Mar 19 '19 at 09:50
  • Can same location repeated on multiple pages ? – Urmi_VV_Developer Mar 19 '19 at 10:26
  • [This answer](https://stackoverflow.com/a/47762053/1729265) shares an idea how to create a PDF with multiple signature fields with individual visualizations which all refer to the same signature value. Beware: *While this procedure creates something which does not violate the letter of the PDF specifications (which only forbid the cases where the same field object is referenced from multiple pages, be it via the same or via distinct widgets), it clearly does violate its intent, its spirit. Thus, this procedure might also become forbidden as part of a Corrigenda document for the specification.* – mkl Mar 19 '19 at 11:04
  • Thanks @mkl , But in shown example it is using certificate chain and set signature container before sending request to Web service , As asked in my question i am getting user certificate and PKCS7 signature both in same XMl sign response. – Urmi_VV_Developer Mar 19 '19 at 12:04
  • As you use a service that returns a full P7 signature container, that is not strictly necessary. Your `public byte[] Sign(Stream data)` merely needs to hash the stream data, request a P7 signature for that hash from your service, and then return the P7 container. Merely if you want the signature widgets to show information from the certificate, you need the certificate beforehand. – mkl Mar 19 '19 at 13:19
  • *"Above code works for single time time signing, ..."* - Have you read my comment [If you need append mode, try to ...](https://stackoverflow.com/questions/55237425/sign-multiple-location-with-same-response-xml-signature-in-pkcs7-cms/55247695#comment97326637_55247695) to my answer? – mkl Mar 22 '19 at 17:19
  • Yes i saw, But if i make that append mode suggested code, then generated pdf shows empty signature containers. Signed file : sendspace.com/file/x415k3 , input file: https://www.sendspace.com/file/9x6w3h, why does it take left corner always, even if providing rect in setvisible signature – Urmi_VV_Developer Mar 25 '19 at 06:10
  • i solved problem of regular placing of signature, modifying code accordingly, but yet append mode issue is still unresolved. For append mode I am using `PdfLiteral PRefLiteral = new PdfLiteral((PRef.Number + reader.NumberOfPages) + " 0 R");` and `PdfStamper stamper = PdfStamper.CreateSignature(reader, os, '\0',null,true );` – Urmi_VV_Developer Mar 25 '19 at 06:45
  • There is an off-by-1 issue I'll still look into. For a first working version, simply take `PdfLiteral PRefLiteral = new PdfLiteral((PRef.Number + reader.NumberOfPages + 1) + " 0 R");` (there is a `+ 1` in contrast to before). – mkl Mar 25 '19 at 11:53
  • @mkl, Thank you so much, it worked and solved problem. – Urmi_VV_Developer Mar 25 '19 at 12:09
  • I'll give a slightly different fix in my answers (to this question and to the often-referenced one). You might want to use that fix, the `+1` fix above only works for PDFs with cross reference streams and object streams (instead of mere cross reference tables). – mkl Mar 25 '19 at 12:24
  • You mean to say that it will work for all PDFs right ? PDFs are of cross reference streams right? By the way here is final signed pdf, which i signed twice in append Mode: https://www.sendspace.com/file/hrut8w , Kindly review it once Thanks! – Urmi_VV_Developer Mar 25 '19 at 12:32
  • The fix with a `+ 1` makes the code work *only with cross reference stream PDFs, not anymore with cross reference table PDFs*. For a universal fix, see the referenced question or my answer here. – mkl Mar 25 '19 at 14:55
  • @mkl, I want to place same sign on some pages- not all pages, then what should be value of `PRefLiteral `, I have list of page numbers. – Urmi_VV_Developer Mar 28 '19 at 13:46
  • I would assume that in that case you replace `reader.NumberOfPages` therein by the number of pages actually signed (also test plus or minus one). – mkl Mar 28 '19 at 15:08
  • @mkl, It worked but once you mentioned you have pdf with is different than mine, Can you share same for testing, Thanks ! – Urmi_VV_Developer Mar 29 '19 at 10:50
  • You mean one with cross reference tables instead of cross reference streams? – mkl Mar 29 '19 at 15:46
  • Yes @mkl, One with cross reference table. – Urmi_VV_Developer Apr 01 '19 at 06:02
  • @mkl, I have tested many PDFs but i don't understand difference between cross reference tables and cross reference streams PDF. My code mostly works with all pdfs. It would be great if you can share any link or pdf file with cross reference table. Thanks .I am new to manipulate pdfs. – Urmi_VV_Developer Apr 02 '19 at 10:46
  • Try it with [this file](https://github.com/mkl-public/testarea-itext5/raw/master/src/test/resources/mkl/testarea/itext5/extract/Vol16_2.pdf), it only has cross reference tables, no cross reference streams and no object streams. – mkl Apr 02 '19 at 12:38
  • Thanks @mkl, It worked for shared file. Just for knowledge can you share link to better understanding upon types of pdf. – Urmi_VV_Developer Apr 03 '19 at 07:23
  • Have a look at the PDF specification, ISO 32000-1; Adobe shared a version without ISO headers [here](https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf). Study chapter 7, in particular sections 7.5.4 "Cross-Reference Table" and 7.5.8 "Cross-Reference Streams". – mkl Apr 03 '19 at 13:22
  • @mkl, Thanks Can you also please check this que it is also related to digital signature but while adding LTV in document: https://stackoverflow.com/questions/55900302/adding-ltv-in-signature-makes-pdf-invalid-using-c-sharp – Urmi_VV_Developer Apr 29 '19 at 09:21

1 Answers1

4

A first quick look through your code revealed two major errors.

Hashing twice

You hash the document data twice (using different APIs for that... weird!):

        Stream data = appearance.GetRangeStream();

        byte[] hash = DigestAlgorithms.Digest(data, "SHA256");

        [...]

        _signatureHash = hash;// signatureHash;
    }
}

[...]
using (SHA256.Create())
{
    _signatureHash = SHA256.Create().ComputeHash(_signatureHash);
}

This is wrong, this makes no sense.

Injecting the wrong signature container

You say

Requesting Esign services give response in PKCS7(CMS) format.

But instead of using the CMS signature container from the result as such, you try to build an own CMS container, injecting the Esign response CMS container as if it was a mere signed hash:

XmlNodeList UserX509Certificate = xmlDoc.GetElementsByTagName("UserX509Certificate");
byte[] rawdat = Convert.FromBase64String(UserX509Certificate[0].InnerText);
var chain = new List<Org.BouncyCastle.X509.X509Certificate>
{
    Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate(new X509Certificate2(rawdat))
};
var signaturee = new PdfPKCS7(null, chain, "SHA256", false);
_signature = signaturee;

_signature.SetExternalDigest(Convert.FromBase64String(signature), null, "RSA");

byte[] encodedSignature = _signature.GetEncodedPKCS7(_hash, null, null, null, CryptoStandard.CMS);

According to your comments in the XML

    <DocSignature error="" id="1" sigHashAlgorithm="SHA256">--Signature in base 64 in PKCS7(CMS)---</DocSignature>

this DocSignature element contains the CMS signature container.

Thus, remove the code segment above and instead put the content of the DocSignature element (don't forget to base64 decode) into the byte[] encodedSignature. Now you can inject it into the prepared signature as before:

IExternalSignatureContainer external = new MyExternalSignatureContainer(encodedSignature);

MakeSignature.SignDeferred(reader, "sign1", os, external);

After you fixed the issues above, two more became apparent:

Using the wrong file mode

You open the stream to write to like this:

using (FileStream os = System.IO.File.OpenWrite(signedPdf))

File.OpenWrite is documented on learn.microsoft.com to be

equivalent to the FileStream(String, FileMode, FileAccess, FileShare) constructor overload with file mode set to OpenOrCreate, the access set to Write, and the share mode set to None.

The file mode OpenOrCreate in turn is documented to specify

that the operating system should open a file if it exists; otherwise, a new file should be created.

Thus, if there already is a file at the given location, that file remains and you start writing into it.

If the new file you create is longer than the old one, this is no problem, you eventually overwrite all the old file content and then the file grows to house the additional new content.

But if the new file you create is shorter than the old one, you have a problem: After the end of the new file there still is data from the old, longer file. Thus, your result is a hodgepodge of two files.

This happened in case of the example files you shared, your new content of "signedPdf.pdf" is only 175982 bytes long but there appears to have been some older file with that name which was 811986 bytes long. Thus, the "signedPdf.pdf" file you shared is 811986 bytes long, the first 175982 bytes containing the result of your operation, the rest data from some other file.

If you cut down your shared "signedPdf.pdf" file to its first 175982 bytes, the result looks much better!

To solve this issue you should use the file mode Create which is documented to be

equivalent to requesting that if the file does not exist, use CreateNew; otherwise, use Truncate.

using (FileStream os = new FileStream(signedPdf, FileMode.Create, FileAccess.Write, FileShare.None))

An issue with your signing service - identity not yet valid

As mentioned above, if you cut down your shared "signedPdf.pdf" file to its first 175982 bytes, the result looks much better! Unfortunately merely better, not yet good:

Signature Panel

The reason for your "identity has expired or is not yet valid" becomes clearer by looking at the details:

Signature Properties

I.e. the signing time claimed by the PDF is 09:47:59 UTC+1.

But looking at the certificate:

Certificate Viewer

I.e. your certificate is valid not before 09:48:40 UTC+1.

Thus, the claimed signing time is more than half a minute before your user certificate became valid! This obviously cannot be accepted by a validator...

Apparently your signing service creates a short-time certificate for you on demand, valid from just then for half an hour. And the time at which you started creating the PDF signature is not in that interval.

I doubt they will change the design of the signing service for your requirements. Thus, you'll have to cheat a bit and use a signing time slightly in the future.

By default the signing time is set to the current by the PdfSignatureAppearance constructor, i.e. when this line executes:

PdfSignatureAppearance appearance = stamper.SignatureAppearance;

Fortunately you can change this claimed signing time if you immediately use

appearance.SignDate = [some other date time];

The date time you should use here has to be shortly (I'd propose not more than 5 minutes) after the time you will call your signing service.

This of course implies that you cannot arbitrarily wait until executing that service call. As soon as you assigned the claimed signing time above, you are committed to have successfully called your signing service shortly before that claimed time!

Furthermore, if that signing service turns out to react only slowly or only after some retries, your software should definitively check the certificate in the signature container you retrieve from it and compare its validity interval with your claimed signing time. If the claimed signing time is not in that interval, start signing again!


Now it became apparent that the AllPagesSignatureContainer you used was designed for a very special use case and still had to be adapted to your use case.

Adapting the AllPagesSignatureContainer for append mode

The AllPagesSignatureContainer implementation essentially copied from this answer worked fine when not signing in append mode but when signing in append mode it failed.

This at first was plausible because that class has to predict the object number that will be used for the signature value. This prediction depends on the exact use case, and switching on append mode changes this use case considerably. Thus, my advice in a comment was

If you need append mode, try to replace the

PdfLiteral PRefLiteral = ...

line in the AllPagesSignatureContainer by

PdfLiteral PRefLiteral = new PdfLiteral((PRef.Number + reader.NumberOfPages) + " 0 R");

In my tests that worked but in your tests it still didn't. An analysis of your signed file turned up the cause: My test file was using cross reference tables while yours was using cross reference streams.

Adapting the AllPagesSignatureContainer for append mode and object streams

iText in append mode uses the compression features of the original file, i.e. in case of your file it creates an object stream as soon as storing an indirect object that allows storage in an object stream.

In case of your file iText reserved an object number for the object stream, and it did so between the time the AllPagesSignatureContainer predicted the signature value object number and the time the signature value actually was generated. Thus, in your file the actual signature value object number was higher than the predicted number by 1.

To solve this for PDFs with cross reference streams, therefore, one can simply replace the PdfLiteral PRefLiteral = ... line by

PdfLiteral PRefLiteral = new PdfLiteral((PRef.Number + reader.NumberOfPages + 1) + " 0 R");

i.e. by adding 1 to the originally predicted value. Unfortunately now the prediction is wrong for PDFs with cross reference tables...

A better way to fix this is to force iText to reserve an object number for the object stream for cross reference stream PDFs before predicting the signature value object number and then use the original prediction code. One way to do this is by creating and writing an indirect object right before the prediction, e.g. like this:

stamper.Writer.AddToBody(new PdfNull(), stamper.Writer.PdfIndirectReference, true);

PdfIndirectReference PRef = stamper.Writer.PdfIndirectReference;
PdfLiteral PRefLiteral = new PdfLiteral((PRef.Number + reader.NumberOfPages) + " 0 R");

The answer the AllPagesSignatureContainer implementation essentially was copied from has been updated accordingly.

mkl
  • 90,588
  • 15
  • 125
  • 265
  • Thanks @mkl I applied changes that you suggested, For first error "Hashing Twice" ,Now Only one hashing method I am using now and creating temp PDF, But created temp pdf shows "Error during signature verification. Error encountered while BER decoding" . I tried changing way of hashing but getting same error. Also i have edited question as per your comments with latest code – Urmi_VV_Developer Mar 20 '19 at 06:29
  • *"But created temp pdf shows"* - The temp pdf file "tempPdf.pdf" is not signed. It is waiting for a signature container to be embedded. The signed pdf file is "signedPdf.pdf". If you meant the latter file, please share it for analysis. – mkl Mar 20 '19 at 08:35
  • @urmivijayvargiya See the new sections of my answer, *Using the wrong file mode* and *An issue with your signing service - identity not yet valid*. – mkl Mar 20 '19 at 11:50
  • Thanks for your input, @mkl For single placeholder it worked, Now I am trying for multiple pages to replicate same image. – Urmi_VV_Developer Mar 22 '19 at 08:11
  • https://stackoverflow.com/questions/47526151/how-to-place-the-same-digital-signatures-to-multiple-places-in-pdf-using-itextsh/47762053#47762053 - Referred this suggested link for same but I don't have chain to reference in AllPagesSignatureContainer, as i am setting annotation before actual sending hash to sign. Chain is available only after sigining. @mkl, please provide input for this concern. – Urmi_VV_Developer Mar 22 '19 at 08:39
  • As you use a service that returns a full P7 signature container, that chain is not strictly necessary. Your public `byte[] Sign(Stream data)` merely needs to hash the stream data, request a P7 signature for that hash from your service, and then return the P7 container. Merely if you want the signature widgets to show information from the certificate, you need the certificate beforehand. – mkl Mar 22 '19 at 09:29
  • I have edited my question, Instead of basic appearance in `MakeSignature.SignExternalContainer(appearance, external, 8192); `i will be passing All sign container's appearance. But i dont know what `byte[] Sign(Stream data) ` should return. @mkl kindly provide input. – Urmi_VV_Developer Mar 22 '19 at 09:50
  • *"But i dont know what `byte[] Sign(Stream data)` should return."* - It shall return a CMS signature container signing the bytes in the `Stream data`. – mkl Mar 22 '19 at 10:57
  • AllPagesSignatureContainer - I am using before signing. To prepare pdf before sending to webservice. Till that i don't have pkcs7 signed signature. or are you asking me to use it at time of `MakeSignature.SignDeferred` method like `MyExternalSignatureContainer` – Urmi_VV_Developer Mar 22 '19 at 11:02
  • So it shall replace the `ExternalBlankSignatureContainer`. Thus simply return the same as `ExternalBlankSignatureContainer` does in its `Sign` method: `return new byte[0];` – mkl Mar 22 '19 at 11:07
  • https://www.sendspace.com/file/x415k3- This signed file is generated after applying changes as per your last comment. Showing other fields as unsigned.@mkl – Urmi_VV_Developer Mar 22 '19 at 11:18
  • The code in your question does not use append mode. The code in `AllPagesSignatureContainer` expects you to sign exactly as demonstrated in that answer, in particular not in append mode. But the sample file you shared is signed in append mode. – mkl Mar 22 '19 at 11:38
  • If you need append mode, try to replace the `PdfLiteral PRefLiteral = ...` line in the `AllPagesSignatureContainer` by `PdfLiteral PRefLiteral = new PdfLiteral((PRef.Number + reader.NumberOfPages) + " 0 R");` – mkl Mar 22 '19 at 12:00
  • It worked your solution for single signer on document but i need multiple people to sign same document, for that i need append mode. i have 2 pages in pdf but after signing both sign comes on same page i guess `Pdfliteral` equation need to be modified , pdf :https://www.sendspace.com/file/xyqzkh – Urmi_VV_Developer Mar 22 '19 at 12:56
  • i accepted ans initially, but I tried with different pdf and it was noticed stamp comes only on left corner and correct rectangle is applied only on first page, refere pdf here: https://www.sendspace.com/file/8rzrd2 , I am updating my code with latest – Urmi_VV_Developer Mar 22 '19 at 13:23
  • Please share the input files for those two signed PDFs. It simply does not make sense that they should be a result of signing using the `AllPagesSignatureContainer`. I'll try to reproduce the output here. If I can reproduce it, I'll try and fix it. If I cannot, then I cannot help. – mkl Mar 22 '19 at 15:07
  • First inputfile: https://www.sendspace.com/file/9x6w3h Second Inputfile: https://www.sendspace.com/file/wh2h2y – Urmi_VV_Developer Mar 25 '19 at 06:07
  • I solved problem of uneven placing signature of rectangle by upading code in `AllPagesSignatureContainer`, in line: `signatureField.SetWidget(new Rectangle(15, 15, 100, 100), null);` same rec as we are passing in setvisible signature. – Urmi_VV_Developer Mar 25 '19 at 07:15
  • *"I solved problem of uneven placing signature of rectangle by"* - ah. ok. Well, that was the obvious place to set the position, so I had thought you would have set it there from the start... – mkl Mar 25 '19 at 11:11
  • Thanks @mkl, Only in append mode now i am facing problem, have updated my question- If you can review. – Urmi_VV_Developer Mar 25 '19 at 11:28
  • @urmi *"Only in append mode now i am facing problem"* - I've updated my answer with an explanation and a fix. – mkl Mar 25 '19 at 15:00
  • @Urmi_VV_Developer Can you full code for multi sign pdf – Dhanasekaran Don Aug 01 '23 at 07:27