Dinesh Patil
Dinesh Patil

Reputation: 114

Digital signature Signer name not showing

In C# Why not showing signer name in pdf when signed by Itextsharp library? I try to crate signed PDF through digital certificate USB Token. When i generate signature on every page that time signature cant show singer name.

Here is the code for getting the certificate:

X509Certificate2 certClient = null;
X509Store st = new X509Store(StoreName.My, StoreLocation.CurrentUser);
string filename = @"..\List1.pdf";
st.Open(OpenFlags.MaxAllowed);
X509Certificate2Collection collection = st.Certificates;
foreach (X509Certificate2 cert in collection)
{                    
    if (cert.Subject.ToLower().Contains("serialnumber"))
    {
        certClient = cert;
        string username = certClient.Subject;
        string startdate = certClient.GetEffectiveDateString();
        string enddate = certClient.GetExpirationDateString();           
    }
}          
st.Close();
IList<X509Certificate> chain = new List<X509Certificate>();
X509Chain x509Chain = new X509Chain();
x509Chain.Build(certClient);
foreach (X509ChainElement x509ChainElement in x509Chain.ChainElements)
{
     chain.Add(DotNetUtilities.FromX509Certificate(x509ChainElement.Certificate));
}
PdfReader inputPdf = new PdfReader(filename);
string dest = @"..\sign10a.pdf";
PdfReader reader = new PdfReader(filename);
FileStream os = new FileStream(dest, FileMode.Create, FileAccess.Write);
PdfStamper stamper = PdfStamper.CreateSignature(reader, os, '\0');
PdfSignatureAppearance appearance = stamper.SignatureAppearance;
appearance.Acro6Layers = false;
appearance.Image = null;
appearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.DESCRIPTION;
appearance.SetVisibleSignature(new iTextSharp.text.Rectangle(100, 10, 250, 100), reader.NumberOfPages, null);
IExternalSignature externalSignature1 = new X509Certificate2Signature(certClient, "SHA-256"); 
AllPagesSignatureContainer allPagesContainer = new AllPagesSignatureContainer(appearance, externalSignature1, chain);
MakeSignature.SignExternalContainer(appearance, allPagesContainer, 8192);
reader.Close();
stamper.Dispose();

And here is my multiple appearance code:

public class AllPagesSignatureContainer : IExternalSignatureContainer
{
    public AllPagesSignatureContainer(PdfSignatureAppearance appearance, IExternalSignature externalSignature, ICollection<X509Certificate> chain)
    {
        this.appearance = appearance;
        this.chain = chain;
        this.externalSignature = externalSignature;
    }

    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 + 1 + 2 * (reader.NumberOfPages - 1)) + " 0 R");

        for (int i = 1; i < reader.NumberOfPages; 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(appearance.Rect, 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)
    {
        String hashAlgorithm = externalSignature.GetHashAlgorithm();
        PdfPKCS7 sgn = new PdfPKCS7(null, chain, hashAlgorithm, false);
        IDigest messageDigest = DigestUtilities.GetDigest(hashAlgorithm);
        byte[] hash = DigestAlgorithms.Digest(data, hashAlgorithm);
        byte[] sh = sgn.getAuthenticatedAttributeBytes(hash, null, null, CryptoStandard.CMS);
        byte[] extSignature = externalSignature.Sign(sh);
        sgn.SetExternalDigest(extSignature, null, externalSignature.GetEncryptionAlgorithm());
        return sgn.GetEncodedPKCS7(hash, null, null, null, CryptoStandard.CMS);            
    }
    PdfSignatureAppearance appearance;
    ICollection<X509Certificate> chain;
    IExternalSignature externalSignature;
}

Digital signature show multiple page but signer name can't display.

enter image description here

I hope it helps, I wrote the code from examples which found on internet. it will work but only singer name not display.

Upvotes: 2

Views: 1082

Answers (1)

mkl
mkl

Reputation: 96029

You wonder why in your visualization

https://i.sstatic.net/lMC0P.png

there is no name after "Digitally signed by".

iTextSharp creates that text line like this:

buf.Append("Digitally signed by ");
String name = null;
CertificateInfo.X509Name x500name = CertificateInfo.GetSubjectFields((X509Certificate)signCertificate);
if (x500name != null) {
    name = x500name.GetField("CN");
    if (name == null)
        name = x500name.GetField("E");
}
if (name == null)
    name = "";
buf.Append(name).Append('\n');

(excerpt from PdfSignatureAppearance.GetAppearance())

signCertificate here is the BouncyCastle X509Certificate otherwise accessible via the PdfSignatureAppearance property Certificate.

But in your code you do not set that appearance.Certificate property. Thus, in the code above x500Name is null. Consequentially name is "" and no name is added after "Digitally signed by ".

If you want that field to be automatically filled in by iText, therefore, provide the necessary information and set appearance.Certificate. Alternatively you can generate the appearance yourself.

Upvotes: 2

Related Questions