I need to sign a PDF document using a certificate that exists in the Windows Certificate Store. I have been digging around all day trying to figure it out, and I am so close yet so far away.
All that is missing is this: How do I get an IExternalSignature object to sign the PDF file with?
Rahul Singla has written a beautiful example of how to sign a PDF document using the new iText 5.3.0 API - as long as you can access a .pfx file sitting around on your PC somewhere.
There is a previous question on signing using a certificate from the Windows Cert Store, except it was using a version of the API where SetCrypto
still exists, and the signature was apparently optional. In iText 5.3.0, the API has changed, and SetCrypto
is no longer a thing.
Here's what I have so far (comments added for posterity, since this might be the most complete and recent version of how to do this on the 'net):
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.security;
using BcX509 = Org.BouncyCastle.X509;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Crypto;
using DotNetUtils = Org.BouncyCastle.Security.DotNetUtilities;
...
// Set up the PDF IO
PdfReader reader = new PdfReader(@"somedirSomeTemplate.pdf");
PdfStamper stamper = PdfStamper.CreateSignature(reader,
new FileStream(@"somedirSignedPdf.pdf", FileMode.Create), '');
PdfSignatureAppearance sap = stamper.SignatureAppearance;
sap.Reason = "For no apparent raisin";
sap.Location = "...";
// Acquire certificate chain
var certStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
certStore.Open(OpenFlags.ReadOnly);
X509CertificateCollection certCollection =
certStore.Certificates.Find(X509FindType.FindBySubjectName,
"My.Cert.Subject", true);
X509Certificate cert = certCollection[0];
// iTextSharp needs this cert as a BouncyCastle X509 object; this converts it.
BcX509.X509Certificate bcCert = DotNetUtils.FromX509Certificate(cert);
var chain = new List<BcX509.X509Certificate> { bcCert };
certStore.Close();
// Ok, that's the certificate chain done. Now how do I get the PKS?
IExternalSignature signature = null; /* ??? */
// Sign the PDF file and finish up.
MakeSignature.SignDetached(sap, signature, chain, // the important stuff
null, null, null, 0, CryptoStandard.CMS);
stamper.Close();
As you can see: I have everything but the signature, and I'm stumped as to how I should obtain it!
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…