c# - 如何使用来自 Windows 证书商店的证书签署 PDF 文档?

标签 c# pdf certificate itextsharp signing

我需要使用 Windows 证书存储中存在的证书来签署 PDF 文档。我整天都在四处挖掘,试图找出答案,但我如此接近如此遥远

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

Rahul Singla编写了一个漂亮的示例,说明如何使用新的 iText 5.3.0 API 签署 PDF 文档 - 只要您可以访问 PC 上某处的 .pfx 文件。

a previous question在使用来自 Windows 证书商店的证书进行签名时,除了它使用的 API 版本仍然存在 SetCrypto,并且签名显然是可选的。在 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<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();

如您所见:除了签名我什么都有,我不知道该如何获得它!

最佳答案

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。

关于c# - 如何使用来自 Windows 证书商店的证书签署 PDF 文档?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14997118/

相关文章:

ruby-on-rails - Ruby - 使用 SSL 连接并通过客户端证书进行身份验证 - sslv3 警报错误证书

c# - 从电子邮件中提取证书

c# - 无法从表存储中获取记录

c# - 使用 Windows 应用商店应用程序设置 SendGrid

django - pyPDF通过django合并并显示为httpresponse

c# - 您可以使用 ITextSharp (c#) 打印 pdf 文件吗?如果是如何?

java - 如何在itext pdf中添加columnText作为注释

c# - 获取当前类的名称

C# 按钮可见性问题

iphone - 如何以编程方式访问 iPhone 受信任的证书存储区?