Search code examples
c#itextsignaturextrareportdigital

Digitally signed a pdf file with multiple different visible digital signatures


Using Devexpress or anything else can I sign a pdf file with multiple digital signatures of multiple signatories in visible form at different locations in a page?

Please see my sample code. It is working for only one digital signature and not showing the visible form of signature.

Please see this image it's showing two different signatory signature in a pdf document I want to get exactly same output but I can only sign via one digital signature

[C#]
    #region #export 
    private void Export() {
        XtraReport1 report = new XtraReport1();


        // Create a new X509Certificate2 object.
        X509Certificate2 certificate = new X509Certificate2();


        // Initialize a local certificate storage and define its options.
        X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
        store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);


        // Initialize a certificate collection and adjust its work.
        X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;
        //X509Certificate2Collection fcollection =
        //    (X509Certificate2Collection)collection.Find(X509FindType.FindByTimeValid, DateTime.Now, true);
        //X509Certificate2Collection scollection =
        //    X509Certificate2UI.SelectFromCollection(fcollection, "Test Certificate Select",
        //        "Select a certificate from the following list to get information on that certificate",
        //        X509SelectionFlag.SingleSelection);
        //if(scollection.Count > 0)
        //    certificate = scollection[0];
        certificate = collection[1];


        // Define the remaining PDF signature options.
        report.ExportOptions.Pdf.SignatureOptions.ContactInfo = "contact info";
        report.ExportOptions.Pdf.SignatureOptions.Location = "location";
        report.ExportOptions.Pdf.SignatureOptions.Reason = "reason";


        // Assign the created certificate to the signature options of the PDF export options.
        report.ExportOptions.Pdf.SignatureOptions.Certificate = certificate;


        // Export the report to a PDF file
        // created in the same folder where the application's .exe file is located.
        report.ExportToPdf("test.pdf");
    }
    #endregion #export

Please see this code I'm using in case of C# iText Sharp

    public string DigiSigTest(string src, string dest, X509Certificate2 pk, string reason, string location, string test_path, string WatermarkLocation, string PageNo, string PdfPassword, string SignPos, string[] Custm, string TokenPin, string[] SignImgLoc, string SignImgPath, string Printdocpath, string[] PrintPageNo)
    {
        PdfReader reader1 = (PdfReader)null;
        PdfReader pdfReader = (PdfReader)null;
        PdfStamper pdfStamper1 = (PdfStamper)null;
        PdfStamper pdfStamper2 = (PdfStamper)null;
        PdfReader reader2 = (PdfReader)null;
        MemoryStream memoryStream1 = new MemoryStream();
        MemoryStream memoryStream2 = new MemoryStream();
        try
        {
            string str1 = src;
            pdfReader = new PdfReader(src);
            int num1 = 1;
            int numberOfPages = pdfReader.NumberOfPages;
            pdfReader.Close();
            int num2 = 0;
            int Width = 0;
            int num3 = 0;
            int Height = 0;
            if ((uint)SignImgLoc.Length > 0U)
            {
                num2 = (int)Convert.ToDecimal(SignImgLoc[0]);
                int num4 = (int)Convert.ToDecimal(SignImgLoc[1]);
                int num5 = (int)Convert.ToDecimal(SignImgLoc[2]);
                int num6 = (int)Convert.ToDecimal(SignImgLoc[3]);
                Width = Math.Abs(num5 - num2);
                Height = Math.Abs(num6 - num4);
                num3 = num4 - Height;
            }
            if (DigiSign.IsPasswordProtected(str1))
            {
                byte[] bytes = Encoding.ASCII.GetBytes(PdfPassword);
                pdfReader = new PdfReader(str1, bytes);
            }
            else
                pdfReader = new PdfReader(str1);
            Rectangle rect = new Rectangle((float)(int)Convert.ToDecimal(Custm[0]), (float)(int)Convert.ToDecimal(Custm[1]), (float)(int)Convert.ToDecimal(Custm[2]), (float)(int)Convert.ToDecimal(Custm[3]));
            string str2 = test_path + "/pdf/" + System.IO.Path.GetFileName(dest);
            PdfReader.unethicalreading = true;
            if (DigiSign.IsPasswordProtected(str1))
            {
                byte[] bytes = Encoding.ASCII.GetBytes(PdfPassword);
                reader1 = new PdfReader(str1, bytes);
            }
            else
                reader1 = new PdfReader(str1);
            pdfStamper1 = new PdfStamper(reader1, (Stream)memoryStream1, char.MinValue, true);
            PdfFormField signature = PdfFormField.CreateSignature(pdfStamper1.Writer);
            signature.SetWidget(rect, (PdfName)null);
            signature.Flags = 4;
            signature.FieldName = "Signature";
            signature.SetPage();
            for (int index = num1; index <= numberOfPages; ++index)
            {
                pdfStamper1.AddAnnotation((PdfAnnotation)signature, index);
                if (PageNo == "FL")
                {
                    pdfStamper1.AddAnnotation((PdfAnnotation)signature, numberOfPages);
                    break;
                }
            }
            pdfStamper1.Close();
            reader1.Close();
            File.WriteAllBytes(str2, memoryStream1.ToArray());
            memoryStream1.Close();
            if (TokenPin.Trim() != "")
            {
                SecureString securePin = this.GetSecurePin(TokenPin);
                RSACryptoServiceProvider privateKey = (RSACryptoServiceProvider)pk.PrivateKey;
                RSACryptoServiceProvider cryptoServiceProvider = new RSACryptoServiceProvider(new CspParameters(1, privateKey.CspKeyContainerInfo.ProviderName, privateKey.CspKeyContainerInfo.KeyContainerName, new CryptoKeySecurity(), securePin));
            }
            if (DigiSign.IsPasswordProtected(str2))
            {
                byte[] bytes = Encoding.ASCII.GetBytes(PdfPassword);
                reader2 = new PdfReader(str2, bytes);
            }
            else
                reader2 = new PdfReader(str2);
            pdfStamper2 = PdfStamper.CreateSignature(reader2, (Stream)memoryStream2, char.MinValue, null, true);
            PdfSignatureAppearance signatureAppearance = pdfStamper2.SignatureAppearance;
            if (reason.Trim() != "")
                signatureAppearance.Reason = reason;
            if (location.Trim() != "")
                signatureAppearance.Location = location;
            signatureAppearance.CertificationLevel = 0;
            signatureAppearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.DESCRIPTION;
            signatureAppearance.Acro6Layers = false;
            signatureAppearance.SetVisibleSignature("Signature");
            if ((uint)SignImgLoc.Length > 0U)
            {
                Image image = DigiSign.resizeImage(Width, Height, SignImgPath);
                image.SetAbsolutePosition((float)num2, (float)num3);
                for (int pageNum = num1; pageNum <= numberOfPages; ++pageNum)
                {
                    pdfStamper2.GetOverContent(pageNum).AddImage(image);
                    if (PageNo == "FL")
                    {
                        pdfStamper2.GetOverContent(numberOfPages).AddImage(image);
                        break;
                    }
                }
            }
            List<Org.BouncyCastle.X509.X509Certificate> x509CertificateList = new List<Org.BouncyCastle.X509.X509Certificate>()
    {
      DotNetUtilities.FromX509Certificate((System.Security.Cryptography.X509Certificates.X509Certificate) pk)
    };
            IExternalSignature externalSignature = (IExternalSignature)new X509Certificate2Signature(pk, "SHA-256");
            MakeSignature.SignDetached(signatureAppearance, externalSignature, (ICollection<Org.BouncyCastle.X509.X509Certificate>)x509CertificateList, (ICollection<ICrlClient>)null, (IOcspClient)null, (ITSAClient)null, 0, CryptoStandard.CMS);
            File.WriteAllBytes(dest, memoryStream2.ToArray());
            File.Delete(str2);
            pdfStamper2.Close();
            reader2.Close();
            return "SUCCESS";
        }
        catch (Exception ex)
        {
            return ex.Message;
        }
        finally
        {
            if (pdfStamper1 != null)
                pdfStamper1.Close();
            if (pdfStamper2 != null)
                pdfStamper2.Close();
            if (reader1 != null)
                reader1.Close();
            if (reader2 != null)
                reader2.Close();
            if (memoryStream1 != null)
                memoryStream1.Close();
            if (memoryStream2 != null)
                memoryStream2.Close();
            if (pdfReader != null)
                pdfReader.Close();
        }
    }

Solution

  • As per mkl says, I have replace

    signature.FieldName = "Signature";

    to

    signature.FieldName = (pk.GetNameInfo(X509NameType.SimpleName, false)).Replace(' ', '_');

    AND

    signatureAppearance.SetVisibleSignature("Signature1");

    to

    signatureAppearance.SetVisibleSignature((pk.GetNameInfo(X509NameType.SimpleName, false)).Replace(' ', '_'));

    Thank you mkl.