如何使用Windows Cert Store中的证书签署PDF文档?

我需要使用Windows证书库中存在的证书来签署PDF文档。 我整天都在努力想弄明白,我 这么远很近

所有缺少的是: 如何获取IExternalSignature对象来签署PDF文件?

Rahul Singla写了一个很好的例子,说明如何使用新的iText 5.3.0 API签署PDF文档 – 只要你可以在某个地方访问PC上的.pfx文件。

有一个关于使用Windows证书存储区中的证书进行签名的问题 ,除了它使用的是仍然存在SetCrypto的API版本,并且签名显然是可选的。 在iText 5.3.0中,API已经改变,而SetCrypto不再是一件事。

以下是我到目前为止所做的评论(为后代添加了评论,因为这可能是如何在’网络上执行此操作的最完整和最新版本):

 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(@"some\dir\SomeTemplate.pdf"); PdfStamper stamper = PdfStamper.CreateSignature(reader, new FileStream(@"some\dir\SignedPdf.pdf", FileMode.Create), '\0'); 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 { 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(); 

正如你所看到的: 除了签名之外我什么都有 ,而且我很难知道如何获得它!

 X509Certificate cert = certCollection[0]; // Your code X509Certificate2 signatureCert = new X509Certificate2(cert); var pk = Org.BouncyCastle.Security.DotNetUtilities.GetKeyPair(signatureCert.PrivateKey).Private; 

如果你有pk,可以如上所述,你创建一个IExternalSignature,如下所示:

 IExternalSignature es = new PrivateKeySignature(pk, "SHA-256"); 

您还可以找到以下使用条款:

请下载有关PDF和数字签名的书籍。 您将在第3章中找到有关如何使用Windows证书库进行签名的Java示例。如您所见,您需要Windows-MY密钥库。

现在转到我们发布这些示例的C#端口的存储库。 寻找C3_11_SignWithToken.cs 。

 X509Store x509Store = new X509Store("My"); x509Store.Open(OpenFlags.ReadOnly); X509Certificate2Collection certificates = x509Store.Certificates; IList chain = new List(); X509Certificate2 pk = null; if (certificates.Count > 0) { X509Certificate2Enumerator certificatesEn = certificates.GetEnumerator(); certificatesEn.MoveNext(); pk = certificatesEn.Current; X509Chain x509chain = new X509Chain(); x509chain.Build(pk); foreach (X509ChainElement x509ChainElement in x509chain.ChainElements) { chain.Add(DotNetUtilities.FromX509Certificate(x509ChainElement.Certificate)); } } x509Store.Close(); 

如果我理解正确chainpk是你正在寻找的变量;

 public byte[] SignPdf(byte[] pdf) { using (MemoryStream output = new MemoryStream()) { //get certificate from path X509Certificate2 cert1 = new X509Certificate2(@"C:\temp\certtemp.pfx", "12345", X509KeyStorageFlags.Exportable); //get private key to sign pdf var pk = Org.BouncyCastle.Security.DotNetUtilities.GetKeyPair(cert1.PrivateKey).Private; // convert the type to be used at .SetCrypt(); Org.BouncyCastle.X509.X509Certificate bcCert = Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate(cert1); // get the pdf u want to sign PdfReader pdfReader = new PdfReader(pdf); PdfStamper stamper = PdfStamper.CreateSignature(pdfReader, output, '\0'); PdfSignatureAppearance pdfSignatureAppearance = stamper.SignatureAppearance; //.SetCrypt(); sign the pdf pdfSignatureAppearance.SetCrypto(pk, new Org.BouncyCastle.X509.X509Certificate[] { bcCert }, null, PdfSignatureAppearance.WINCER_SIGNED); pdfSignatureAppearance.Reason = "Este documento está assinado digitalmente pelo Estado Portugues"; pdfSignatureAppearance.Location = " Lisboa, Portugal"; pdfSignatureAppearance.SignDate = DateTime.Now; stamper.Close(); return output.ToArray(); } } 

我使用此代码获取byte[] PDF并再次返回已签名的byte[] PDF。

这是iTextSharp-LGPL。