Reputation: 114
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.
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
Reputation: 96029
You wonder why in your visualization
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